summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:13:19 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:13:19 +0200
commitff01b716711b97c2fcaa709ea97f7650f106aa10 (patch)
tree50dd4d687f38f50c4e136af030c02c267c769f3a /3rdparty/asio/src
parent2a138159c30457aecd9e9679be5159704db0f954 (diff)
Added ASIO networking library (nw)
Diffstat (limited to '3rdparty/asio/src')
-rw-r--r--3rdparty/asio/src/.gitignore11
-rw-r--r--3rdparty/asio/src/Makefile.am15
-rw-r--r--3rdparty/asio/src/Makefile.mgw213
-rw-r--r--3rdparty/asio/src/Makefile.msc452
-rw-r--r--3rdparty/asio/src/asio.cpp11
-rw-r--r--3rdparty/asio/src/asio_ssl.cpp11
-rw-r--r--3rdparty/asio/src/doc/.gitignore5
-rw-r--r--3rdparty/asio/src/doc/Jamfile.v262
-rw-r--r--3rdparty/asio/src/doc/asio.pngbin0 -> 3164 bytes
-rw-r--r--3rdparty/asio/src/doc/asio.qbk116
-rw-r--r--3rdparty/asio/src/doc/asioref.sty90
-rw-r--r--3rdparty/asio/src/doc/asioref.xsl94
-rw-r--r--3rdparty/asio/src/doc/boost_bind_dox.txt5
-rw-r--r--3rdparty/asio/src/doc/doxy2qbk.pl22
-rw-r--r--3rdparty/asio/src/doc/examples.qbk419
-rw-r--r--3rdparty/asio/src/doc/history.qbk1214
-rw-r--r--3rdparty/asio/src/doc/index.xml13
-rw-r--r--3rdparty/asio/src/doc/makepdf.pl26
-rw-r--r--3rdparty/asio/src/doc/noncopyable_dox.txt3
-rw-r--r--3rdparty/asio/src/doc/overview.qbk97
-rw-r--r--3rdparty/asio/src/doc/overview/allocation.qbk58
-rw-r--r--3rdparty/asio/src/doc/overview/async.qbk185
-rw-r--r--3rdparty/asio/src/doc/overview/async_op1.dot78
-rw-r--r--3rdparty/asio/src/doc/overview/async_op1.pngbin0 -> 24260 bytes
-rw-r--r--3rdparty/asio/src/doc/overview/async_op2.dot78
-rw-r--r--3rdparty/asio/src/doc/overview/async_op2.pngbin0 -> 24542 bytes
-rw-r--r--3rdparty/asio/src/doc/overview/basics.qbk106
-rw-r--r--3rdparty/asio/src/doc/overview/bsd_sockets.qbk270
-rw-r--r--3rdparty/asio/src/doc/overview/buffers.qbk163
-rw-r--r--3rdparty/asio/src/doc/overview/coroutine.qbk51
-rw-r--r--3rdparty/asio/src/doc/overview/cpp2011.qbk275
-rw-r--r--3rdparty/asio/src/doc/overview/handler_tracking.qbk102
-rw-r--r--3rdparty/asio/src/doc/overview/implementation.qbk305
-rw-r--r--3rdparty/asio/src/doc/overview/iostreams.qbk72
-rw-r--r--3rdparty/asio/src/doc/overview/line_based.qbk118
-rw-r--r--3rdparty/asio/src/doc/overview/other_protocols.qbk94
-rw-r--r--3rdparty/asio/src/doc/overview/posix.qbk152
-rw-r--r--3rdparty/asio/src/doc/overview/proactor.dot100
-rw-r--r--3rdparty/asio/src/doc/overview/proactor.pngbin0 -> 30877 bytes
-rw-r--r--3rdparty/asio/src/doc/overview/protocols.qbk149
-rw-r--r--3rdparty/asio/src/doc/overview/rationale.qbk54
-rw-r--r--3rdparty/asio/src/doc/overview/reactor.qbk44
-rw-r--r--3rdparty/asio/src/doc/overview/serial_ports.qbk45
-rw-r--r--3rdparty/asio/src/doc/overview/signals.qbk44
-rw-r--r--3rdparty/asio/src/doc/overview/spawn.qbk102
-rw-r--r--3rdparty/asio/src/doc/overview/ssl.qbk123
-rw-r--r--3rdparty/asio/src/doc/overview/strands.qbk85
-rw-r--r--3rdparty/asio/src/doc/overview/streams.qbk62
-rw-r--r--3rdparty/asio/src/doc/overview/sync_op.dot67
-rw-r--r--3rdparty/asio/src/doc/overview/sync_op.pngbin0 -> 20243 bytes
-rw-r--r--3rdparty/asio/src/doc/overview/threads.qbk66
-rw-r--r--3rdparty/asio/src/doc/overview/timers.qbk52
-rw-r--r--3rdparty/asio/src/doc/overview/windows.qbk126
-rw-r--r--3rdparty/asio/src/doc/project-root.jam1
-rw-r--r--3rdparty/asio/src/doc/quickref.xml514
-rw-r--r--3rdparty/asio/src/doc/reference.dox256
-rw-r--r--3rdparty/asio/src/doc/reference.qbk112844
-rw-r--r--3rdparty/asio/src/doc/reference.xsl1779
-rw-r--r--3rdparty/asio/src/doc/release_checklist.htm68
-rw-r--r--3rdparty/asio/src/doc/requirements/AcceptHandler.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/AcceptableProtocol.qbk25
-rw-r--r--3rdparty/asio/src/doc/requirements/AsyncRandomAccessReadDevice.qbk56
-rw-r--r--3rdparty/asio/src/doc/requirements/AsyncRandomAccessWriteDevice.qbk57
-rw-r--r--3rdparty/asio/src/doc/requirements/AsyncReadStream.qbk50
-rw-r--r--3rdparty/asio/src/doc/requirements/AsyncWriteStream.qbk48
-rw-r--r--3rdparty/asio/src/doc/requirements/BufferedHandshakeHandler.qbk55
-rw-r--r--3rdparty/asio/src/doc/requirements/CompletionCondition.qbk42
-rw-r--r--3rdparty/asio/src/doc/requirements/CompletionHandler.qbk63
-rw-r--r--3rdparty/asio/src/doc/requirements/ConnectCondition.qbk34
-rw-r--r--3rdparty/asio/src/doc/requirements/ConnectHandler.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/ConstBufferSequence.qbk55
-rw-r--r--3rdparty/asio/src/doc/requirements/DynamicBuffer.qbk93
-rw-r--r--3rdparty/asio/src/doc/requirements/Endpoint.qbk94
-rw-r--r--3rdparty/asio/src/doc/requirements/EndpointSequence.qbk30
-rw-r--r--3rdparty/asio/src/doc/requirements/ExecutionContext.qbk36
-rw-r--r--3rdparty/asio/src/doc/requirements/Executor.qbk141
-rw-r--r--3rdparty/asio/src/doc/requirements/GettableSerialPortOption.qbk33
-rw-r--r--3rdparty/asio/src/doc/requirements/GettableSocketOption.qbk67
-rw-r--r--3rdparty/asio/src/doc/requirements/Handler.qbk64
-rw-r--r--3rdparty/asio/src/doc/requirements/HandshakeHandler.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/InternetProtocol.qbk47
-rw-r--r--3rdparty/asio/src/doc/requirements/IoControlCommand.qbk34
-rw-r--r--3rdparty/asio/src/doc/requirements/IoObjectService.qbk62
-rw-r--r--3rdparty/asio/src/doc/requirements/IteratorConnectHandler.qbk81
-rw-r--r--3rdparty/asio/src/doc/requirements/MoveAcceptHandler.qbk61
-rw-r--r--3rdparty/asio/src/doc/requirements/MutableBufferSequence.qbk56
-rw-r--r--3rdparty/asio/src/doc/requirements/ProtoAllocator.qbk19
-rw-r--r--3rdparty/asio/src/doc/requirements/Protocol.qbk54
-rw-r--r--3rdparty/asio/src/doc/requirements/RangeConnectHandler.qbk82
-rw-r--r--3rdparty/asio/src/doc/requirements/ReadHandler.qbk79
-rw-r--r--3rdparty/asio/src/doc/requirements/ResolveHandler.qbk82
-rw-r--r--3rdparty/asio/src/doc/requirements/Service.qbk40
-rw-r--r--3rdparty/asio/src/doc/requirements/SettableSerialPortOption.qbk33
-rw-r--r--3rdparty/asio/src/doc/requirements/SettableSocketOption.qbk54
-rw-r--r--3rdparty/asio/src/doc/requirements/ShutdownHandler.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/SignalHandler.qbk79
-rw-r--r--3rdparty/asio/src/doc/requirements/SyncRandomAccessReadDevice.qbk49
-rw-r--r--3rdparty/asio/src/doc/requirements/SyncRandomAccessWriteDevice.qbk49
-rw-r--r--3rdparty/asio/src/doc/requirements/SyncReadStream.qbk41
-rw-r--r--3rdparty/asio/src/doc/requirements/SyncWriteStream.qbk39
-rw-r--r--3rdparty/asio/src/doc/requirements/TimeTraits.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/WaitHandler.qbk72
-rw-r--r--3rdparty/asio/src/doc/requirements/WaitTraits.qbk52
-rw-r--r--3rdparty/asio/src/doc/requirements/WriteHandler.qbk79
-rw-r--r--3rdparty/asio/src/doc/requirements/asynchronous_operations.qbk281
-rw-r--r--3rdparty/asio/src/doc/requirements/asynchronous_socket_operations.qbk39
-rw-r--r--3rdparty/asio/src/doc/requirements/read_write_operations.qbk34
-rw-r--r--3rdparty/asio/src/doc/requirements/synchronous_socket_operations.qbk37
-rw-r--r--3rdparty/asio/src/doc/std_exception_dox.txt7
-rw-r--r--3rdparty/asio/src/doc/tutorial.dox226
-rw-r--r--3rdparty/asio/src/doc/tutorial.qbk2227
-rw-r--r--3rdparty/asio/src/doc/tutorial.xsl437
-rw-r--r--3rdparty/asio/src/doc/using.qbk316
-rw-r--r--3rdparty/asio/src/examples/cpp03/Makefile.am250
-rw-r--r--3rdparty/asio/src/examples/cpp03/allocation/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/allocation/server.cpp238
-rw-r--r--3rdparty/asio/src/examples/cpp03/buffers/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/buffers/reference_counted.cpp131
-rw-r--r--3rdparty/asio/src/examples/cpp03/chat/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/chat/chat_client.cpp177
-rw-r--r--3rdparty/asio/src/examples/cpp03/chat/chat_message.hpp93
-rw-r--r--3rdparty/asio/src/examples/cpp03/chat/chat_server.cpp247
-rw-r--r--3rdparty/asio/src/examples/cpp03/chat/posix_chat_client.cpp204
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp137
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp92
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp59
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp79
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp59
-rw-r--r--3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp53
-rw-r--r--3rdparty/asio/src/examples/cpp03/fork/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/fork/daemon.cpp189
-rw-r--r--3rdparty/asio/src/examples/cpp03/fork/process_per_connection.cpp160
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/client/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/client/async_client.cpp204
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/client/sync_client.cpp106
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/doc_root/data_1K.html28
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/doc_root/data_2K.html49
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/doc_root/data_4K.html91
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/doc_root/data_8K.html175
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/connection.cpp99
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/connection.hpp83
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/connection_manager.cpp38
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/connection_manager.hpp44
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/header.hpp28
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/main.cpp44
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/mime_types.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/mime_types.hpp27
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/reply.cpp256
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/reply.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/request.hpp34
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/request_handler.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/request_handler.hpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/request_parser.cpp315
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/request_parser.hpp95
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/server.cpp94
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server/server.hpp69
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/connection.cpp93
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/connection.hpp75
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/header.hpp28
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.cpp69
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.hpp57
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/main.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/mime_types.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/mime_types.hpp27
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/reply.cpp256
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/reply.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/request.hpp34
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/request_handler.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/request_handler.hpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/request_parser.cpp315
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/request_parser.hpp95
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/server.cpp77
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server2/server.hpp68
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/connection.cpp98
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/connection.hpp78
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/header.hpp28
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/main.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/mime_types.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/mime_types.hpp27
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/reply.cpp256
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/reply.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/request.hpp34
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/request_handler.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/request_handler.hpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/request_parser.cpp315
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/request_parser.hpp95
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/server.cpp89
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server3/server.hpp70
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/file_handler.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/file_handler.hpp44
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/header.hpp28
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/main.cpp58
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/mime_types.cpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/mime_types.hpp27
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/reply.cpp256
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/reply.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/request.hpp46
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/request_parser.cpp226
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/request_parser.hpp78
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/server.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/http/server4/server.hpp73
-rw-r--r--3rdparty/asio/src/examples/cpp03/icmp/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp94
-rw-r--r--3rdparty/asio/src/examples/cpp03/icmp/ipv4_header.hpp102
-rw-r--r--3rdparty/asio/src/examples/cpp03/icmp/ping.cpp161
-rw-r--r--3rdparty/asio/src/examples/cpp03/invocation/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp162
-rw-r--r--3rdparty/asio/src/examples/cpp03/iostreams/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/iostreams/daytime_client.cpp44
-rw-r--r--3rdparty/asio/src/examples/cpp03/iostreams/daytime_server.cpp51
-rw-r--r--3rdparty/asio/src/examples/cpp03/iostreams/http_client.cpp91
-rw-r--r--3rdparty/asio/src/examples/cpp03/local/.gitignore13
-rw-r--r--3rdparty/asio/src/examples/cpp03/local/connect_pair.cpp141
-rw-r--r--3rdparty/asio/src/examples/cpp03/local/iostream_client.cpp62
-rw-r--r--3rdparty/asio/src/examples/cpp03/local/stream_client.cpp61
-rw-r--r--3rdparty/asio/src/examples/cpp03/local/stream_server.cpp141
-rw-r--r--3rdparty/asio/src/examples/cpp03/multicast/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/multicast/receiver.cpp93
-rw-r--r--3rdparty/asio/src/examples/cpp03/multicast/sender.cpp99
-rw-r--r--3rdparty/asio/src/examples/cpp03/nonblocking/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp240
-rw-r--r--3rdparty/asio/src/examples/cpp03/porthopper/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/porthopper/client.cpp192
-rw-r--r--3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp156
-rw-r--r--3rdparty/asio/src/examples/cpp03/porthopper/server.cpp189
-rw-r--r--3rdparty/asio/src/examples/cpp03/serialization/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/serialization/client.cpp125
-rw-r--r--3rdparty/asio/src/examples/cpp03/serialization/connection.hpp188
-rw-r--r--3rdparty/asio/src/examples/cpp03/serialization/server.cpp123
-rw-r--r--3rdparty/asio/src/examples/cpp03/serialization/stock.hpp50
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp83
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp97
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/logger.hpp24
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/logger_service.cpp17
-rw-r--r--3rdparty/asio/src/examples/cpp03/services/logger_service.hpp145
-rw-r--r--3rdparty/asio/src/examples/cpp03/socks4/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp144
-rw-r--r--3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp94
-rw-r--r--3rdparty/asio/src/examples/cpp03/spawn/.gitignore12
-rw-r--r--3rdparty/asio/src/examples/cpp03/spawn/echo_server.cpp122
-rw-r--r--3rdparty/asio/src/examples/cpp03/spawn/parallel_grep.cpp89
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/README8
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/ca.pem49
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/client.cpp156
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/dh2048.pem8
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/server.cpp170
-rw-r--r--3rdparty/asio/src/examples/cpp03/ssl/server.pem71
-rw-r--r--3rdparty/asio/src/examples/cpp03/timeouts/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp308
-rw-r--r--3rdparty/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp242
-rw-r--r--3rdparty/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp182
-rw-r--r--3rdparty/asio/src/examples/cpp03/timeouts/server.cpp427
-rw-r--r--3rdparty/asio/src/examples/cpp03/timers/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/timers/tick_count_timer.cpp123
-rw-r--r--3rdparty/asio/src/examples/cpp03/timers/time_t_timer.cpp93
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime1/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime1/client.cpp57
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime2/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime2/server.cpp50
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime3/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime3/server.cpp117
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime4/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime4/client.cpp52
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime5/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime5/server.cpp58
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime6/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime6/server.cpp89
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime7/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime7/server.cpp158
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/daytime_dox.txt502
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/index_dox.txt48
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer1/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer1/timer.cpp25
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer2/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer2/timer.cpp30
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer3/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer3/timer.cpp44
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer4/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer4/timer.cpp55
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer5/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer5/timer.cpp81
-rw-r--r--3rdparty/asio/src/examples/cpp03/tutorial/timer_dox.txt383
-rw-r--r--3rdparty/asio/src/examples/cpp03/windows/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp03/windows/transmit_file.cpp171
-rw-r--r--3rdparty/asio/src/examples/cpp11/Makefile.am92
-rw-r--r--3rdparty/asio/src/examples/cpp11/allocation/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp11/allocation/server.cpp213
-rw-r--r--3rdparty/asio/src/examples/cpp11/buffers/.gitignore10
-rw-r--r--3rdparty/asio/src/examples/cpp11/buffers/reference_counted.cpp121
-rw-r--r--3rdparty/asio/src/examples/cpp11/chat/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp11/chat/chat_client.cpp167
-rw-r--r--3rdparty/asio/src/examples/cpp11/chat/chat_message.hpp91
-rw-r--r--3rdparty/asio/src/examples/cpp11/chat/chat_server.cpp227
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp114
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/async_udp_echo_server.cpp82
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp55
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp74
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp58
-rw-r--r--3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_server.cpp52
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/.gitignore5
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/actor.cpp286
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/bank_account_1.cpp54
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/bank_account_2.cpp54
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/fork_join.cpp327
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/pipeline.cpp298
-rw-r--r--3rdparty/asio/src/examples/cpp11/executors/priority_scheduler.cpp168
-rw-r--r--3rdparty/asio/src/examples/cpp11/futures/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp11/futures/daytime_client.cpp94
-rw-r--r--3rdparty/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp201
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/connection.cpp94
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/connection.hpp79
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/connection_manager.cpp40
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/connection_manager.hpp48
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/header.hpp28
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/main.cpp43
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/mime_types.cpp45
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/mime_types.hpp27
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/reply.cpp255
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/reply.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/request.hpp34
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/request_handler.cpp121
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/request_handler.hpp47
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/request_parser.cpp315
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/request_parser.hpp96
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/server.cpp94
-rw-r--r--3rdparty/asio/src/examples/cpp11/http/server/server.hpp64
-rw-r--r--3rdparty/asio/src/examples/cpp11/iostreams/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp11/iostreams/http_client.cpp91
-rw-r--r--3rdparty/asio/src/examples/cpp11/spawn/.gitignore12
-rw-r--r--3rdparty/asio/src/examples/cpp11/spawn/echo_server.cpp108
-rw-r--r--3rdparty/asio/src/examples/cpp11/spawn/parallel_grep.cpp84
-rw-r--r--3rdparty/asio/src/examples/cpp14/Makefile.am48
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/async_tcp_echo_server.cpp117
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/async_udp_echo_server.cpp83
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp55
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_server.cpp77
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp59
-rw-r--r--3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_server.cpp53
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/.gitignore6
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/actor.cpp281
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/async_1.cpp47
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/async_2.cpp68
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/bank_account_1.cpp54
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/bank_account_2.cpp53
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/fork_join.cpp326
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/pipeline.cpp293
-rw-r--r--3rdparty/asio/src/examples/cpp14/executors/priority_scheduler.cpp167
-rw-r--r--3rdparty/asio/src/examples/cpp14/iostreams/.gitignore11
-rw-r--r--3rdparty/asio/src/examples/cpp14/iostreams/http_client.cpp91
-rw-r--r--3rdparty/asio/src/tests/.gitignore11
-rw-r--r--3rdparty/asio/src/tests/Makefile.am416
-rw-r--r--3rdparty/asio/src/tests/latency/.gitignore11
-rw-r--r--3rdparty/asio/src/tests/latency/allocator.hpp52
-rw-r--r--3rdparty/asio/src/tests/latency/coroutine.hpp87
-rw-r--r--3rdparty/asio/src/tests/latency/high_res_clock.hpp53
-rw-r--r--3rdparty/asio/src/tests/latency/tcp_client.cpp124
-rw-r--r--3rdparty/asio/src/tests/latency/tcp_server.cpp114
-rw-r--r--3rdparty/asio/src/tests/latency/udp_client.cpp104
-rw-r--r--3rdparty/asio/src/tests/latency/udp_server.cpp125
-rw-r--r--3rdparty/asio/src/tests/latency/unyield.hpp21
-rw-r--r--3rdparty/asio/src/tests/latency/yield.hpp23
-rw-r--r--3rdparty/asio/src/tests/performance/.gitignore11
-rw-r--r--3rdparty/asio/src/tests/performance/client.cpp286
-rw-r--r--3rdparty/asio/src/tests/performance/handler_allocator.hpp112
-rw-r--r--3rdparty/asio/src/tests/performance/server.cpp233
-rw-r--r--3rdparty/asio/src/tests/unit/.gitignore74
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/async_ops.hpp415
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/async_result.hpp78
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/deprecated_async_ops.hpp345
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/deprecated_async_result.hpp82
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/gettable_socket_option.hpp54
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/io_control_command.hpp32
-rw-r--r--3rdparty/asio/src/tests/unit/archetypes/settable_socket_option.hpp49
-rw-r--r--3rdparty/asio/src/tests/unit/associated_allocator.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/associated_executor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/async_result.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_datagram_socket.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_deadline_timer.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_raw_socket.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_seq_packet_socket.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_serial_port.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/basic_signal_set.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_socket_acceptor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_stream_socket.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_streambuf.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/basic_waitable_timer.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/bind_executor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/buffer.cpp567
-rw-r--r--3rdparty/asio/src/tests/unit/buffered_read_stream.cpp346
-rw-r--r--3rdparty/asio/src/tests/unit/buffered_stream.cpp372
-rw-r--r--3rdparty/asio/src/tests/unit/buffered_write_stream.cpp361
-rw-r--r--3rdparty/asio/src/tests/unit/buffers_iterator.cpp292
-rw-r--r--3rdparty/asio/src/tests/unit/completion_condition.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/connect.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/coroutine.cpp112
-rw-r--r--3rdparty/asio/src/tests/unit/datagram_socket_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/deadline_timer.cpp392
-rw-r--r--3rdparty/asio/src/tests/unit/deadline_timer_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/defer.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/dispatch.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/error.cpp89
-rw-r--r--3rdparty/asio/src/tests/unit/execution_context.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/executor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/executor_work_guard.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/generic/.gitignore14
-rw-r--r--3rdparty/asio/src/tests/unit/generic/basic_endpoint.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/generic/datagram_protocol.cpp267
-rw-r--r--3rdparty/asio/src/tests/unit/generic/raw_protocol.cpp267
-rw-r--r--3rdparty/asio/src/tests/unit/generic/seq_packet_protocol.cpp209
-rw-r--r--3rdparty/asio/src/tests/unit/generic/stream_protocol.cpp252
-rw-r--r--3rdparty/asio/src/tests/unit/high_resolution_timer.cpp30
-rw-r--r--3rdparty/asio/src/tests/unit/io_context.cpp362
-rw-r--r--3rdparty/asio/src/tests/unit/ip/.gitignore28
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address.cpp144
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v4.cpp324
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v4_iterator.cpp27
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v4_range.cpp27
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v6.cpp409
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v6_iterator.cpp27
-rw-r--r--3rdparty/asio/src/tests/unit/ip/address_v6_range.cpp27
-rw-r--r--3rdparty/asio/src/tests/unit/ip/basic_endpoint.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/basic_resolver.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/basic_resolver_entry.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/basic_resolver_iterator.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/basic_resolver_query.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/host_name.cpp55
-rw-r--r--3rdparty/asio/src/tests/unit/ip/icmp.cpp684
-rw-r--r--3rdparty/asio/src/tests/unit/ip/multicast.cpp363
-rw-r--r--3rdparty/asio/src/tests/unit/ip/network_v4.cpp301
-rw-r--r--3rdparty/asio/src/tests/unit/ip/network_v6.cpp225
-rw-r--r--3rdparty/asio/src/tests/unit/ip/resolver_query_base.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/resolver_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ip/tcp.cpp1372
-rw-r--r--3rdparty/asio/src/tests/unit/ip/udp.cpp783
-rw-r--r--3rdparty/asio/src/tests/unit/ip/unicast.cpp171
-rw-r--r--3rdparty/asio/src/tests/unit/ip/v6_only.cpp135
-rw-r--r--3rdparty/asio/src/tests/unit/is_read_buffered.cpp129
-rw-r--r--3rdparty/asio/src/tests/unit/is_write_buffered.cpp129
-rw-r--r--3rdparty/asio/src/tests/unit/local/.gitignore13
-rw-r--r--3rdparty/asio/src/tests/unit/local/basic_endpoint.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/local/connect_pair.cpp76
-rw-r--r--3rdparty/asio/src/tests/unit/local/datagram_protocol.cpp236
-rw-r--r--3rdparty/asio/src/tests/unit/local/stream_protocol.cpp213
-rw-r--r--3rdparty/asio/src/tests/unit/packaged_task.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/placeholders.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/posix/.gitignore15
-rw-r--r--3rdparty/asio/src/tests/unit/posix/basic_descriptor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/posix/basic_stream_descriptor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/posix/descriptor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/posix/descriptor_base.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/posix/stream_descriptor.cpp185
-rw-r--r--3rdparty/asio/src/tests/unit/posix/stream_descriptor_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/post.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/raw_socket_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/read.cpp3927
-rw-r--r--3rdparty/asio/src/tests/unit/read_at.cpp7493
-rw-r--r--3rdparty/asio/src/tests/unit/read_until.cpp887
-rw-r--r--3rdparty/asio/src/tests/unit/seq_packet_socket_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/serial_port.cpp171
-rw-r--r--3rdparty/asio/src/tests/unit/serial_port_base.cpp99
-rw-r--r--3rdparty/asio/src/tests/unit/serial_port_service.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/signal_set.cpp97
-rw-r--r--3rdparty/asio/src/tests/unit/signal_set_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/socket_acceptor_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/socket_base.cpp639
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/.gitignore14
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/context.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/context_base.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/rfc2818_verification.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/stream.cpp199
-rw-r--r--3rdparty/asio/src/tests/unit/ssl/stream_base.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/steady_timer.cpp30
-rw-r--r--3rdparty/asio/src/tests/unit/strand.cpp224
-rw-r--r--3rdparty/asio/src/tests/unit/stream_socket_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/streambuf.cpp62
-rw-r--r--3rdparty/asio/src/tests/unit/system_timer.cpp400
-rw-r--r--3rdparty/asio/src/tests/unit/thread.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/time_traits.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/unit_test.hpp175
-rw-r--r--3rdparty/asio/src/tests/unit/use_future.cpp1346
-rw-r--r--3rdparty/asio/src/tests/unit/uses_executor.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/wait_traits.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/waitable_timer_service.cpp25
-rw-r--r--3rdparty/asio/src/tests/unit/windows/.gitignore21
-rw-r--r--3rdparty/asio/src/tests/unit/windows/basic_handle.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/basic_object_handle.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/basic_random_access_handle.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/basic_stream_handle.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/object_handle.cpp126
-rw-r--r--3rdparty/asio/src/tests/unit/windows/object_handle_service.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/overlapped_handle.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/overlapped_ptr.cpp95
-rw-r--r--3rdparty/asio/src/tests/unit/windows/random_access_handle.cpp151
-rw-r--r--3rdparty/asio/src/tests/unit/windows/random_access_handle_service.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/windows/stream_handle.cpp144
-rw-r--r--3rdparty/asio/src/tests/unit/windows/stream_handle_service.cpp26
-rw-r--r--3rdparty/asio/src/tests/unit/write.cpp3922
-rw-r--r--3rdparty/asio/src/tests/unit/write_at.cpp7554
-rw-r--r--3rdparty/asio/src/tools/handlerviz.pl299
509 files changed, 192990 insertions, 0 deletions
diff --git a/3rdparty/asio/src/.gitignore b/3rdparty/asio/src/.gitignore
new file mode 100644
index 00000000000..8a91ad86de7
--- /dev/null
+++ b/3rdparty/asio/src/.gitignore
@@ -0,0 +1,11 @@
+Makefile
+Makefile.in
+.deps
+*.a
+*.o
+*.obj
+*.lib
+*.pdb
+*.log
+*.trs
+*.dirstamp
diff --git a/3rdparty/asio/src/Makefile.am b/3rdparty/asio/src/Makefile.am
new file mode 100644
index 00000000000..c308ea0a769
--- /dev/null
+++ b/3rdparty/asio/src/Makefile.am
@@ -0,0 +1,15 @@
+if STANDALONE
+SUBDIRS = examples/cpp11 tests
+else
+SUBDIRS = examples/cpp03 tests
+endif
+
+DIST_SUBDIRS = examples/cpp03 examples/cpp11 examples/cpp14 tests
+
+EXTRA_DIST = \
+ Makefile.mgw \
+ Makefile.msc \
+ tools/handlerviz.pl
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
diff --git a/3rdparty/asio/src/Makefile.mgw b/3rdparty/asio/src/Makefile.mgw
new file mode 100644
index 00000000000..ffbb1f27c93
--- /dev/null
+++ b/3rdparty/asio/src/Makefile.mgw
@@ -0,0 +1,213 @@
+ifndef BOOSTDIR
+BOOSTDIR = ../../boost_1_34_1
+endif
+
+CXXFLAGS = -g -O2 -Wall -mthreads -I../include -I$(BOOSTDIR)
+LDFLAGS = -g -O2 -mthreads
+LIBS = -lws2_32 -lmswsock
+DEFINES = -D_WIN32_WINNT=0x0501
+
+PERFORMANCE_TEST_EXES = \
+ tests/performance/client.exe \
+ tests/performance/server.exe
+
+UNIT_TEST_EXES = \
+ tests/unit/basic_datagram_socket.exe \
+ tests/unit/basic_deadline_timer.exe \
+ tests/unit/basic_raw_socket.exe \
+ tests/unit/basic_seq_packet_socket.exe \
+ tests/unit/basic_serial_port.exe \
+ tests/unit/basic_signal_set.exe \
+ tests/unit/basic_socket_acceptor.exe \
+ tests/unit/basic_stream_socket.exe \
+ tests/unit/basic_streambuf.exe \
+ tests/unit/basic_waitable_timer.exe \
+ tests/unit/buffered_read_stream.exe \
+ tests/unit/buffered_stream.exe \
+ tests/unit/buffered_write_stream.exe \
+ tests/unit/buffer.exe \
+ tests/unit/buffers_iterator.exe \
+ tests/unit/completion_condition.exe \
+ tests/unit/connect.exe \
+ tests/unit/coroutine.exe \
+ tests/unit/datagram_socket_service.exe \
+ tests/unit/deadline_timer_service.exe \
+ tests/unit/deadline_timer.exe \
+ tests/unit/error.exe \
+ tests/unit/generic/basic_endpoint.exe \
+ tests/unit/generic/datagram_protocol.exe \
+ tests/unit/generic/raw_protocol.exe \
+ tests/unit/generic/seq_packet_protocol.exe \
+ tests/unit/generic/stream_protocol.exe \
+ tests/unit/high_resolution_timer.exe \
+ tests/unit/io_context.exe \
+ tests/unit/ip/address.exe \
+ tests/unit/ip/address_v4.exe \
+ tests/unit/ip/address_v6.exe \
+ tests/unit/ip/basic_endpoint.exe \
+ tests/unit/ip/basic_resolver.exe \
+ tests/unit/ip/basic_resolver_entry.exe \
+ tests/unit/ip/basic_resolver_iterator.exe \
+ tests/unit/ip/basic_resolver_query.exe \
+ tests/unit/ip/host_name.exe \
+ tests/unit/ip/icmp.exe \
+ tests/unit/ip/multicast.exe \
+ tests/unit/ip/resolver_query_base.exe \
+ tests/unit/ip/resolver_service.exe \
+ tests/unit/ip/tcp.exe \
+ tests/unit/ip/udp.exe \
+ tests/unit/ip/unicast.exe \
+ tests/unit/ip/v6_only.exe \
+ tests/unit/is_read_buffered.exe \
+ tests/unit/is_write_buffered.exe \
+ tests/unit/placeholders.exe \
+ tests/unit/raw_socket_service.exe \
+ tests/unit/read.exe \
+ tests/unit/read_at.exe \
+ tests/unit/read_until.exe \
+ tests/unit/seq_packet_socket_service.exe \
+ tests/unit/serial_port.exe \
+ tests/unit/serial_port_base.exe \
+ tests/unit/serial_port_service.exe \
+ tests/unit/signal_set.exe \
+ tests/unit/signal_set_service.exe \
+ tests/unit/socket_acceptor_service.exe \
+ tests/unit/socket_base.exe \
+ tests/unit/steady_timer.exe \
+ tests/unit/strand.exe \
+ tests/unit/stream_socket_service.exe \
+ tests/unit/streambuf.exe \
+ tests/unit/system_timer.exe \
+ tests/unit/thread.exe \
+ tests/unit/time_traits.exe \
+ tests/unit/waitable_timer_service.exe \
+ tests/unit/windows/basic_handle.exe \
+ tests/unit/windows/basic_object_handle.exe \
+ tests/unit/windows/basic_random_access_handle.exe \
+ tests/unit/windows/basic_stream_handle.exe \
+ tests/unit/windows/object_handle.exe \
+ tests/unit/windows/object_handle_service.exe \
+ tests/unit/windows/overlapped_ptr.exe \
+ tests/unit/windows/random_access_handle.exe \
+ tests/unit/windows/random_access_handle_service.exe \
+ tests/unit/windows/stream_handle.exe \
+ tests/unit/windows/stream_handle_service.exe \
+ tests/unit/write.exe \
+ tests/unit/write_at.exe
+
+EXAMPLE_EXES = \
+ examples/cpp03/allocation/server.exe \
+ examples/cpp03/buffers/reference_counted.exe \
+ examples/cpp03/chat/chat_client.exe \
+ examples/cpp03/chat/chat_server.exe \
+ examples/cpp03/echo/async_tcp_echo_server.exe \
+ examples/cpp03/echo/async_udp_echo_server.exe \
+ examples/cpp03/echo/blocking_tcp_echo_client.exe \
+ examples/cpp03/echo/blocking_tcp_echo_server.exe \
+ examples/cpp03/echo/blocking_udp_echo_client.exe \
+ examples/cpp03/echo/blocking_udp_echo_server.exe \
+ examples/cpp03/http/client/async_client.exe \
+ examples/cpp03/http/client/sync_client.exe \
+ examples/cpp03/icmp/ping.exe \
+ examples/cpp03/invocation/prioritised_handlers.exe \
+ examples/cpp03/iostreams/daytime_client.exe \
+ examples/cpp03/iostreams/daytime_server.exe \
+ examples/cpp03/iostreams/http_client.exe \
+ examples/cpp03/multicast/receiver.exe \
+ examples/cpp03/multicast/sender.exe \
+ examples/cpp03/socks4/sync_client.exe \
+ examples/cpp03/timeouts/async_tcp_client.exe \
+ examples/cpp03/timeouts/blocking_tcp_client.exe \
+ examples/cpp03/timeouts/blocking_udp_client.exe \
+ examples/cpp03/timeouts/server.exe \
+ examples/cpp03/timers/tick_count_timer.exe \
+ examples/cpp03/timers/time_t_timer.exe \
+ examples/cpp03/tutorial/timer1/timer.exe \
+ examples/cpp03/tutorial/timer2/timer.exe \
+ examples/cpp03/tutorial/timer3/timer.exe \
+ examples/cpp03/tutorial/timer4/timer.exe \
+ examples/cpp03/tutorial/timer5/timer.exe \
+ examples/cpp03/tutorial/daytime1/client.exe \
+ examples/cpp03/tutorial/daytime2/server.exe \
+ examples/cpp03/tutorial/daytime3/server.exe \
+ examples/cpp03/tutorial/daytime4/client.exe \
+ examples/cpp03/tutorial/daytime5/server.exe \
+ examples/cpp03/tutorial/daytime6/server.exe \
+ examples/cpp03/tutorial/daytime7/server.exe \
+ examples/cpp03/windows/transmit_file.exe
+
+OTHER_EXAMPLE_EXES = \
+ examples/cpp03/http/server/http_server.exe \
+ examples/cpp03/http/server2/http_server.exe \
+ examples/cpp03/http/server3/http_server.exe \
+ examples/cpp03/services/daytime_client.exe
+
+all: \
+ $(PERFORMANCE_TEST_EXES) \
+ $(UNIT_TEST_EXES) \
+ $(EXAMPLE_EXES) \
+ $(OTHER_EXAMPLE_EXES)
+
+check: $(UNIT_TEST_EXES) $(addprefix run.,$(UNIT_TEST_EXES))
+
+$(addprefix run.,$(UNIT_TEST_EXES))::
+ @echo === Running $(@:run.%=%) ===
+ @$(@:run.%=%)
+ @echo.
+
+clean:
+ -rm -f $(PERFORMANCE_TEST_EXES)
+ -rm -f $(PERFORMANCE_TEST_EXES:.exe=.o)
+ -rm -f $(UNIT_TEST_OBJ)
+ -rm -f $(UNIT_TEST_EXES)
+ -rm -f $(UNIT_TEST_EXES:.exe=.o)
+ -rm -f $(EXAMPLE_EXES)
+ -rm -f $(EXAMPLE_EXES:.exe=.o)
+ -rm -f $(OTHER_EXAMPLE_EXES)
+ -rm -f $(OTHER_EXAMPLE_EXES:.exe=.o)
+
+$(UNIT_TEST_EXES): %.exe: %.o
+ g++ -o$@ $(LDFLAGS) $< $(LIBS)
+
+$(PERFORMANCE_TEST_EXES) $(EXAMPLE_EXES): %.exe: %.o
+ g++ -o$@ $(LDFLAGS) $< $(LIBS)
+
+examples/cpp03/http/server/http_server.exe: \
+ examples/cpp03/http/server/connection.o \
+ examples/cpp03/http/server/connection_manager.o \
+ examples/cpp03/http/server/main.o \
+ examples/cpp03/http/server/mime_types.o \
+ examples/cpp03/http/server/reply.o \
+ examples/cpp03/http/server/request_handler.o \
+ examples/cpp03/http/server/request_parser.o \
+ examples/cpp03/http/server/server.o
+ g++ -o$@ $(LDFLAGS) $^ $(LIBS)
+
+examples/cpp03/http/server2/http_server.exe: \
+ examples/cpp03/http/server2/connection.o \
+ examples/cpp03/http/server2/io_context_pool.o \
+ examples/cpp03/http/server2/main.o \
+ examples/cpp03/http/server2/mime_types.o \
+ examples/cpp03/http/server2/reply.o \
+ examples/cpp03/http/server2/request_handler.o \
+ examples/cpp03/http/server2/request_parser.o \
+ examples/cpp03/http/server2/server.o
+ g++ -o$@ $(LDFLAGS) $^ $(LIBS)
+
+examples/cpp03/http/server3/http_server.exe: \
+ examples/cpp03/http/server3/connection.o \
+ examples/cpp03/http/server3/main.o \
+ examples/cpp03/http/server3/mime_types.o \
+ examples/cpp03/http/server3/reply.o \
+ examples/cpp03/http/server3/request_handler.o \
+ examples/cpp03/http/server3/request_parser.o \
+ examples/cpp03/http/server3/server.o
+ g++ -o$@ $(LDFLAGS) $^ $(LIBS)
+
+examples/cpp03/services/daytime_client.exe: \
+ examples/cpp03/services/daytime_client.o \
+ examples/cpp03/services/logger_service.o
+ g++ -o$@ $(LDFLAGS) $^ $(LIBS)
+
+.cpp.o:
+ g++ -o$@ -c $(CXXFLAGS) $(DEFINES) $<
diff --git a/3rdparty/asio/src/Makefile.msc b/3rdparty/asio/src/Makefile.msc
new file mode 100644
index 00000000000..7cb1c56d7f2
--- /dev/null
+++ b/3rdparty/asio/src/Makefile.msc
@@ -0,0 +1,452 @@
+!ifndef BOOSTDIR
+BOOSTDIR = ../../boost_1_34_1
+!endif
+
+COMMON_CXXFLAGS = -nologo -EHac -GR -I. -I../include
+
+!ifdef WARNINGS
+WARNINGS_CXXFLAGS = -W4 -wd4512 -wd4447
+!endif
+
+!ifdef STATICRTL
+! ifdef DEBUG
+DEBUG_CXXFLAGS = -Zi -MTd
+! else
+DEBUG_CXXFLAGS = -O2 -MT
+! endif
+!else
+! ifdef DEBUG
+DEBUG_CXXFLAGS = -Zi -MDd
+! else
+DEBUG_CXXFLAGS = -O2 -MD
+! endif
+!endif
+
+!ifdef UNICODE
+UNICODE_CXXFLAGS = -DUNICODE -D_UNICODE
+!endif
+
+!ifdef TRACKING
+TRACKING_CXXFLAGS = -DASIO_ENABLE_HANDLER_TRACKING
+!endif
+
+!ifndef _WIN32_WINNT
+! ifdef STORE
+_WIN32_WINNT=0x0603
+! else
+_WIN32_WINNT=0x0501
+! endif
+!endif
+
+!ifdef WIN9X
+DEFINES = \
+ -DASIO_DISABLE_IOCP \
+ -D_WIN32_WINNT=$(_WIN32_WINNT) \
+ -DBOOST_ALL_NO_LIB
+!else
+! ifdef STORE
+DEFINES = \
+ -DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP \
+ -DBOOST_ALL_NO_LIB -D_WIN32_WINNT=$(_WIN32_WINNT) \
+ -DUNICODE -D_UNICODE
+! else
+! ifdef WINRT
+DEFINES = \
+ -ZW -FI SDKDDKVer.h -FI winapifamily.h -DWINAPI_FAMILY=WINAPI_PARTITION_APP \
+ -DBOOST_ALL_NO_LIB
+! else
+DEFINES = \
+ -D_WIN32_WINNT=$(_WIN32_WINNT) \
+ -DBOOST_ALL_NO_LIB
+! endif
+! endif
+!endif
+
+!ifdef SEPARATE_COMPILATION
+LIBS = asio.lib
+SEPARATE_COMPILATION_CXXFLAGS = \
+ -DASIO_SEPARATE_COMPILATION \
+ -DASIO_ENABLE_CANCELIO
+!endif
+
+!ifdef STANDALONE
+STANDALONE_CXXFLAGS = -DASIO_STANDALONE
+!else
+STANDALONE_CXXFLAGS = -I$(BOOSTDIR)
+!endif
+
+CXXFLAGS = \
+ $(COMMON_CXXFLAGS) \
+ $(WARNINGS_CXXFLAGS) \
+ $(DEBUG_CXXFLAGS) \
+ $(UNICODE_CXXFLAGS) \
+ $(TRACKING_CXXFLAGS) \
+ $(SEPARATE_COMPILATION_CXXFLAGS) \
+ $(STANDALONE_CXXFLAGS)
+
+!ifndef SSLDIR
+SSLDIR = ../../openssl-0.9.8g
+!endif
+
+SSL_CXXFLAGS = -I$(SSLDIR)/inc32
+
+SSL_LIBS = \
+ $(SSLDIR)/out32/libeay32.lib \
+ $(SSLDIR)/out32/ssleay32.lib \
+ user32.lib advapi32.lib gdi32.lib
+
+LATENCY_TEST_EXES = \
+ tests\latency\tcp_client.exe \
+ tests\latency\tcp_server.exe \
+ tests\latency\udp_client.exe \
+ tests\latency\udp_server.exe
+
+PERFORMANCE_TEST_EXES = \
+ tests\performance\client.exe \
+ tests\performance\server.exe
+
+UNIT_TEST_EXES = \
+ tests\unit\basic_datagram_socket.exe \
+ tests\unit\basic_deadline_timer.exe \
+ tests\unit\basic_raw_socket.exe \
+ tests\unit\basic_seq_packet_socket.exe \
+ tests\unit\basic_serial_port.exe \
+ tests\unit\basic_signal_set.exe \
+ tests\unit\basic_socket_acceptor.exe \
+ tests\unit\basic_stream_socket.exe \
+ tests\unit\basic_streambuf.exe \
+ tests\unit\basic_waitable_timer.exe \
+ tests\unit\buffered_read_stream.exe \
+ tests\unit\buffered_stream.exe \
+ tests\unit\buffered_write_stream.exe \
+ tests\unit\buffer.exe \
+ tests\unit\buffers_iterator.exe \
+ tests\unit\completion_condition.exe \
+ tests\unit\connect.exe \
+ tests\unit\coroutine.exe \
+ tests\unit\datagram_socket_service.exe \
+ tests\unit\deadline_timer_service.exe \
+ tests\unit\deadline_timer.exe \
+ tests\unit\error.exe \
+ tests\unit\generic\basic_endpoint.exe \
+ tests\unit\generic\datagram_protocol.exe \
+ tests\unit\generic\raw_protocol.exe \
+ tests\unit\generic\seq_packet_protocol.exe \
+ tests\unit\generic\stream_protocol.exe \
+ tests\unit\high_resolution_timer.exe \
+ tests\unit\io_context.exe \
+ tests\unit\ip\address.exe \
+ tests\unit\ip\address_v4.exe \
+ tests\unit\ip\address_v6.exe \
+ tests\unit\ip\basic_endpoint.exe \
+ tests\unit\ip\basic_resolver.exe \
+ tests\unit\ip\basic_resolver_entry.exe \
+ tests\unit\ip\basic_resolver_iterator.exe \
+ tests\unit\ip\basic_resolver_query.exe \
+ tests\unit\ip\host_name.exe \
+ tests\unit\ip\icmp.exe \
+ tests\unit\ip\multicast.exe \
+ tests\unit\ip\resolver_query_base.exe \
+ tests\unit\ip\resolver_service.exe \
+ tests\unit\ip\tcp.exe \
+ tests\unit\ip\udp.exe \
+ tests\unit\ip\unicast.exe \
+ tests\unit\ip\v6_only.exe \
+ tests\unit\is_read_buffered.exe \
+ tests\unit\is_write_buffered.exe \
+ tests\unit\placeholders.exe \
+ tests\unit\raw_socket_service.exe \
+ tests\unit\read.exe \
+ tests\unit\read_at.exe \
+ tests\unit\read_until.exe \
+ tests\unit\seq_packet_socket_service.exe \
+ tests\unit\serial_port.exe \
+ tests\unit\serial_port_base.exe \
+ tests\unit\serial_port_service.exe \
+ tests\unit\signal_set.exe \
+ tests\unit\signal_set_service.exe \
+ tests\unit\socket_acceptor_service.exe \
+ tests\unit\socket_base.exe \
+ tests\unit\strand.exe \
+ tests\unit\steady_timer.exe \
+ tests\unit\stream_socket_service.exe \
+ tests\unit\streambuf.exe \
+ tests\unit\system_timer.exe \
+ tests\unit\thread.exe \
+ tests\unit\time_traits.exe \
+ tests\unit\waitable_timer_service.exe \
+ tests\unit\windows\basic_handle.exe \
+ tests\unit\windows\basic_object_handle.exe \
+ tests\unit\windows\basic_random_access_handle.exe \
+ tests\unit\windows\basic_stream_handle.exe \
+ tests\unit\windows\object_handle.exe \
+ tests\unit\windows\object_handle_service.exe \
+ tests\unit\windows\overlapped_ptr.exe \
+ tests\unit\windows\random_access_handle.exe \
+ tests\unit\windows\random_access_handle_service.exe \
+ tests\unit\windows\stream_handle.exe \
+ tests\unit\windows\stream_handle_service.exe \
+ tests\unit\write.exe \
+ tests\unit\write_at.exe
+
+CPP03_EXAMPLE_EXES = \
+ examples\cpp03\allocation\server.exe \
+ examples\cpp03\buffers\reference_counted.exe \
+ examples\cpp03\chat\chat_client.exe \
+ examples\cpp03\chat\chat_server.exe \
+ examples\cpp03\echo\async_tcp_echo_server.exe \
+ examples\cpp03\echo\async_udp_echo_server.exe \
+ examples\cpp03\echo\blocking_tcp_echo_client.exe \
+ examples\cpp03\echo\blocking_tcp_echo_server.exe \
+ examples\cpp03\echo\blocking_udp_echo_client.exe \
+ examples\cpp03\echo\blocking_udp_echo_server.exe \
+ examples\cpp03\http\client\async_client.exe \
+ examples\cpp03\http\client\sync_client.exe \
+ examples\cpp03\http\server\http_server.exe \
+ examples\cpp03\http\server2\http_server.exe \
+ examples\cpp03\http\server3\http_server.exe \
+ examples\cpp03\http\server4\http_server.exe \
+ examples\cpp03\icmp\ping.exe \
+ examples\cpp03\invocation\prioritised_handlers.exe \
+ examples\cpp03\iostreams\daytime_client.exe \
+ examples\cpp03\iostreams\daytime_server.exe \
+ examples\cpp03\iostreams\http_client.exe \
+ examples\cpp03\multicast\receiver.exe \
+ examples\cpp03\multicast\sender.exe \
+ examples\cpp03\nonblocking\third_party_lib.exe \
+ examples\cpp03\porthopper\client.exe \
+ examples\cpp03\porthopper\server.exe \
+ examples\cpp03\services\daytime_client.exe \
+ examples\cpp03\socks4\sync_client.exe \
+ examples\cpp03\timeouts\async_tcp_client.exe \
+ examples\cpp03\timeouts\blocking_tcp_client.exe \
+ examples\cpp03\timeouts\blocking_udp_client.exe \
+ examples\cpp03\timeouts\server.exe \
+ examples\cpp03\timers\tick_count_timer.exe \
+ examples\cpp03\timers\time_t_timer.exe \
+ examples\cpp03\tutorial\timer1\timer.exe \
+ examples\cpp03\tutorial\timer2\timer.exe \
+ examples\cpp03\tutorial\timer3\timer.exe \
+ examples\cpp03\tutorial\timer4\timer.exe \
+ examples\cpp03\tutorial\timer5\timer.exe \
+ examples\cpp03\tutorial\daytime1\client.exe \
+ examples\cpp03\tutorial\daytime2\server.exe \
+ examples\cpp03\tutorial\daytime3\server.exe \
+ examples\cpp03\tutorial\daytime4\client.exe \
+ examples\cpp03\tutorial\daytime5\server.exe \
+ examples\cpp03\tutorial\daytime6\server.exe \
+ examples\cpp03\tutorial\daytime7\server.exe \
+ examples\cpp03\windows\transmit_file.exe
+
+SSL_UNIT_TEST_EXES = \
+ tests\unit\ssl\basic_context.exe \
+ tests\unit\ssl\context.exe \
+ tests\unit\ssl\context_base.exe \
+ tests\unit\ssl\context_service.exe \
+ tests\unit\ssl\rfc2818_verification.exe \
+ tests\unit\ssl\stream.exe \
+ tests\unit\ssl\stream_base.exe \
+ tests\unit\ssl\stream_service.exe
+
+SSL_EXAMPLE_EXES = \
+ examples\cpp03\ssl\client.exe \
+ examples\cpp03\ssl\server.exe
+
+!ifdef SEPARATE_COMPILATION
+all: asio.lib
+asio.lib: asio.cpp
+ cl -Fe$@ -Foasio.obj $(CXXFLAGS) $(DEFINES) -c asio.cpp
+ lib -name:asio.lib asio.obj
+!endif
+
+!ifdef STANDALONE
+all: \
+ $(UNIT_TEST_EXES)
+!else
+all: \
+ $(LATENCY_TEST_EXES) \
+ $(PERFORMANCE_TEST_EXES) \
+ $(UNIT_TEST_EXES) \
+ $(CPP03_EXAMPLE_EXES)
+!endif
+
+ssl: \
+ $(SSL_UNIT_TEST_EXES) \
+ $(SSL_EXAMPLE_EXES)
+
+check: $(UNIT_TEST_EXES)
+ !@echo === Running $** === && $** && echo.
+
+{tests\latency}.cpp{tests\latency}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{tests\performance}.cpp{tests\performance}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+tests\unit\unit_test.obj: tests\unit\unit_test.cpp
+ cl -Fe$@ -Fotests\unit\unit_test.obj $(CXXFLAGS) $(DEFINES) -c tests\unit\unit_test.cpp
+
+{tests\unit}.cpp{tests\unit}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{tests\unit\generic}.cpp{tests\unit\generic}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{tests\unit\ip}.cpp{tests\unit\ip}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{tests\unit\ssl}.cpp{tests\unit\ssl}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(SSL_CXXFLAGS) $(DEFINES) $< $(SSL_LIBS) $(LIBS) -link -opt:ref
+
+{tests\unit\windows}.cpp{tests\unit\windows}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\allocation}.cpp{examples\cpp03\allocation}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\buffers}.cpp{examples\cpp03\buffers}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\chat}.cpp{examples\cpp03\chat}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\echo}.cpp{examples\cpp03\echo}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\http\client}.cpp{examples\cpp03\http\client}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\icmp}.cpp{examples\cpp03\icmp}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\invocation}.cpp{examples\cpp03\invocation}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\iostreams}.cpp{examples\cpp03\iostreams}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\multicast}.cpp{examples\cpp03\multicast}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\nonblocking}.cpp{examples\cpp03\nonblocking}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\porthopper}.cpp{examples\cpp03\porthopper}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\socks4}.cpp{examples\cpp03\socks4}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\ssl}.cpp{examples\cpp03\ssl}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(SSL_CXXFLAGS) $(DEFINES) $< $(SSL_LIBS) $(LIBS) -link -opt:ref
+
+{examples\cpp03\timeouts}.cpp{examples\cpp03\timeouts}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\timers}.cpp{examples\cpp03\timers}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\timer1}.cpp{examples\cpp03\tutorial\timer1}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\timer2}.cpp{examples\cpp03\tutorial\timer2}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\timer3}.cpp{examples\cpp03\tutorial\timer3}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\timer4}.cpp{examples\cpp03\tutorial\timer4}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\timer5}.cpp{examples\cpp03\tutorial\timer5}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime1}.cpp{examples\cpp03\tutorial\daytime1}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime2}.cpp{examples\cpp03\tutorial\daytime2}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime3}.cpp{examples\cpp03\tutorial\daytime3}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime4}.cpp{examples\cpp03\tutorial\daytime4}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime5}.cpp{examples\cpp03\tutorial\daytime5}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime6}.cpp{examples\cpp03\tutorial\daytime6}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\tutorial\daytime7}.cpp{examples\cpp03\tutorial\daytime7}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp03\windows}.cpp{examples\cpp03\windows}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+{examples\cpp11\executors}.cpp{examples\cpp11\executors}.exe:
+ cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref
+
+examples\cpp03\http\server\http_server.exe: \
+ examples\cpp03\http\server\connection.cpp \
+ examples\cpp03\http\server\connection_manager.cpp \
+ examples\cpp03\http\server\main.cpp \
+ examples\cpp03\http\server\mime_types.cpp \
+ examples\cpp03\http\server\reply.cpp \
+ examples\cpp03\http\server\request_handler.cpp \
+ examples\cpp03\http\server\request_parser.cpp \
+ examples\cpp03\http\server\server.cpp
+ cl -Fe$@ -Foexamples\cpp03\http\server\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref
+
+examples\cpp03\http\server2\http_server.exe: \
+ examples\cpp03\http\server2\connection.cpp \
+ examples\cpp03\http\server2\io_context_pool.cpp \
+ examples\cpp03\http\server2\main.cpp \
+ examples\cpp03\http\server2\mime_types.cpp \
+ examples\cpp03\http\server2\reply.cpp \
+ examples\cpp03\http\server2\request_handler.cpp \
+ examples\cpp03\http\server2\request_parser.cpp \
+ examples\cpp03\http\server2\server.cpp
+ cl -Fe$@ -Foexamples\cpp03\http\server2\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref
+
+examples\cpp03\http\server3\http_server.exe: \
+ examples\cpp03\http\server3\connection.cpp \
+ examples\cpp03\http\server3\main.cpp \
+ examples\cpp03\http\server3\mime_types.cpp \
+ examples\cpp03\http\server3\reply.cpp \
+ examples\cpp03\http\server3\request_handler.cpp \
+ examples\cpp03\http\server3\request_parser.cpp \
+ examples\cpp03\http\server3\server.cpp
+ cl -Fe$@ -Foexamples\cpp03\http\server3\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref
+
+examples\cpp03\http\server4\http_server.exe: \
+ examples\cpp03\http\server4\file_handler.cpp \
+ examples\cpp03\http\server4\main.cpp \
+ examples\cpp03\http\server4\mime_types.cpp \
+ examples\cpp03\http\server4\reply.cpp \
+ examples\cpp03\http\server4\request_parser.cpp \
+ examples\cpp03\http\server4\server.cpp
+ cl -Fe$@ -Foexamples\cpp03\http\server4\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref
+
+examples\cpp03\services\daytime_client.exe: \
+ examples\cpp03\services\daytime_client.cpp \
+ examples\cpp03\services\logger_service.cpp
+ cl -Fe$@ -Foexamples\cpp03\services\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref
+
+clean:
+ -del /q /s asio.lib
+ -del /q /s asio.obj
+ -del /q /s tests\*.exe
+ -del /q /s tests\*.exe.manifest
+ -del /q /s tests\*.exp
+ -del /q /s tests\*.ilk
+ -del /q /s tests\*.pdb
+ -del /q /s tests\*.obj
+ -del /q /s examples\*.exe
+ -del /q /s examples\*.exe.manifest
+ -del /q /s examples\*.exp
+ -del /q /s examples\*.ilk
+ -del /q /s examples\*.pdb
+ -del /q /s examples\*.obj
+ -del /q /s *.pdb
diff --git a/3rdparty/asio/src/asio.cpp b/3rdparty/asio/src/asio.cpp
new file mode 100644
index 00000000000..2125d620fee
--- /dev/null
+++ b/3rdparty/asio/src/asio.cpp
@@ -0,0 +1,11 @@
+//
+// asio.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio/impl/src.hpp"
diff --git a/3rdparty/asio/src/asio_ssl.cpp b/3rdparty/asio/src/asio_ssl.cpp
new file mode 100644
index 00000000000..68a16c0c5f1
--- /dev/null
+++ b/3rdparty/asio/src/asio_ssl.cpp
@@ -0,0 +1,11 @@
+//
+// asio_ssl.cpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio/ssl/impl/src.hpp"
diff --git a/3rdparty/asio/src/doc/.gitignore b/3rdparty/asio/src/doc/.gitignore
new file mode 100644
index 00000000000..32e513ae33f
--- /dev/null
+++ b/3rdparty/asio/src/doc/.gitignore
@@ -0,0 +1,5 @@
+bin
+html
+reference.tags
+asio.docbook
+*.pdf
diff --git a/3rdparty/asio/src/doc/Jamfile.v2 b/3rdparty/asio/src/doc/Jamfile.v2
new file mode 100644
index 00000000000..3e22af7cffe
--- /dev/null
+++ b/3rdparty/asio/src/doc/Jamfile.v2
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2003-2016 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)
+#
+
+project asio-doc ;
+
+import os ;
+local boost = [ os.environ BOOST_ROOT ] ;
+
+using quickbook ;
+
+xml asio : asio.qbk ;
+
+boostbook standalone
+ :
+ asio
+ :
+ <xsl:param>boost.image.src=asio.png
+ <xsl:param>boost.image.alt="asio C++ library"
+ <xsl:param>boost.image.w=250
+ <xsl:param>boost.image.h=60
+ <xsl:param>nav.layout=none
+ <xsl:param>navig.graphics.path=""
+ <xsl:param>admon.graphics.path=""
+ <xsl:param>chapter.autolabel=0
+ <xsl:param>chunk.section.depth=8
+ <xsl:param>chunk.first.sections=1
+ <xsl:param>toc.section.depth=2
+ <xsl:param>toc.max.depth=1
+ <xsl:param>generate.section.toc.level=1
+ <xsl:param>generate.toc="chapter nop section nop"
+ ;
+
+install html
+ :
+ $(boost)/doc/src/boostbook.css
+ $(boost)/doc/src/images/blank.png
+ $(boost)/doc/src/images/caution.png
+ $(boost)/doc/src/images/draft.png
+ $(boost)/doc/src/images/home.png
+ $(boost)/doc/src/images/important.png
+ $(boost)/doc/src/images/next_disabled.png
+ $(boost)/doc/src/images/next.png
+ $(boost)/doc/src/images/note.png
+ $(boost)/doc/src/images/prev_disabled.png
+ $(boost)/doc/src/images/prev.png
+ $(boost)/doc/src/images/tip.png
+ $(boost)/doc/src/images/up_disabled.png
+ $(boost)/doc/src/images/up.png
+ $(boost)/doc/src/images/warning.png
+ overview/proactor.png
+ overview/sync_op.png
+ overview/async_op1.png
+ overview/async_op2.png
+ asio.png
+ ;
+
+install asioref : standalone : <location>. <format>docbook ;
+explicit asioref ;
diff --git a/3rdparty/asio/src/doc/asio.png b/3rdparty/asio/src/doc/asio.png
new file mode 100644
index 00000000000..c05fd3a4514
--- /dev/null
+++ b/3rdparty/asio/src/doc/asio.png
Binary files differ
diff --git a/3rdparty/asio/src/doc/asio.qbk b/3rdparty/asio/src/doc/asio.qbk
new file mode 100644
index 00000000000..68cc2e0e4d2
--- /dev/null
+++ b/3rdparty/asio/src/doc/asio.qbk
@@ -0,0 +1,116 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[library Asio
+ [quickbook 1.4]
+ [copyright 2003 - 2016 Christopher M. Kohlhoff]
+ [purpose Networking library]
+ [license
+ 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])
+ ]
+ [category template]
+ [category generic]
+]
+
+[template mdash[] '''&mdash; ''']
+[template half_open_range[text] '''&#91;'''[text])]
+[template indexterm1[id term1] '''<indexterm id="'''[id]'''"><primary>'''[term1]'''</primary></indexterm>''']
+[template indexterm2[id term1 term2] '''<indexterm id="'''[id]'''"><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
+[template inline_note[text] \[['Note:] [text] '''&mdash;'''['end note]\] ]
+[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
+[def __POSIX__ /POSIX/]
+[def __Windows__ /Windows/]
+[def __accept__ [@http://www.opengroup.org/onlinepubs/000095399/functions/accept.html `accept()`]]
+[def __connect__ [@http://www.opengroup.org/onlinepubs/000095399/functions/connect.html `connect()`]]
+[def __getpeername__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getpeername.html `getpeername()`]]
+[def __getsockname__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getsockname.html `getsockname()`]]
+[def __getsockopt__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getsockopt.html `getsockopt()`]]
+[def __ioctl__ [@http://www.opengroup.org/onlinepubs/000095399/functions/ioctl.html `ioctl()`]]
+[def __poll__ [@http://www.opengroup.org/onlinepubs/000095399/functions/poll.html `poll()`]]
+[def __recvfrom__ [@http://www.opengroup.org/onlinepubs/000095399/functions/recvfrom.html `recvfrom()`]]
+[def __sendto__ [@http://www.opengroup.org/onlinepubs/000095399/functions/sendto.html `sendto()`]]
+[def __setsockopt__ [@http://www.opengroup.org/onlinepubs/000095399/functions/setsockopt.html `setsockopt()`]]
+[def __shutdown__ [@http://www.opengroup.org/onlinepubs/000095399/functions/shutdown.html `shutdown()`]]
+[def __socket__ [@http://www.opengroup.org/onlinepubs/000095399/functions/socket.html `socket()`]]
+
+[/=============================================================================]
+
+Asio is a cross-platform C++ library for network and low-level I/O programming
+that provides developers with a consistent asynchronous model using a modern
+C++ approach.
+
+[variablelist
+ [
+ [
+ [link asio.overview Overview]
+ ]
+ [
+ An overview of the features included in Asio, plus rationale and design information.
+ ]
+ ]
+ [
+ [
+ [link asio.using Using Asio]
+ ]
+ [
+ How to use Asio in your applications. Includes information on
+ library dependencies and supported platforms.
+ ]
+ ]
+ [
+ [
+ [link asio.tutorial Tutorial]
+ ]
+ [
+ A tutorial that introduces the fundamental concepts required to use
+ Asio, and shows how to use Asio to develop simple client and
+ server programs.
+ ]
+ ]
+ [
+ [
+ [link asio.examples Examples]
+ ]
+ [
+ Examples that illustrate the use of Asio in more complex applications.
+ ]
+ ]
+ [
+ [
+ [link asio.reference Reference]
+ ]
+ [
+ Detailed class and function reference.
+ ]
+ ]
+ [
+ [
+ [link asio.history Revision History]
+ ]
+ [
+ Log of Asio changes made in each release.
+ ]
+ ]
+ [
+ [
+ [link asio.index Index]
+ ]
+ [
+ Book-style text index of Asio documentation.
+ ]
+ ]
+]
+
+[include overview.qbk]
+[include using.qbk]
+[include tutorial.qbk]
+[include examples.qbk]
+[include reference.qbk]
+[include history.qbk]
+[xinclude index.xml]
diff --git a/3rdparty/asio/src/doc/asioref.sty b/3rdparty/asio/src/doc/asioref.sty
new file mode 100644
index 00000000000..2bf5a8d0e91
--- /dev/null
+++ b/3rdparty/asio/src/doc/asioref.sty
@@ -0,0 +1,90 @@
+%%
+%% This is a DocBook LaTeX style for Asio
+%%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{mybook}[2008/11/11 Asio DocBook Style]
+
+% The defined options
+\DeclareOption{hyperlink}{ \def\DBKhyperlink{yes} }
+\DeclareOption{nohyperlink}{ \def\DBKhyperlink{no} }
+
+% Default values
+\ExecuteOptions{nohyperlink}
+
+% If defined, process the options
+\ProcessOptions\relax
+
+% Needed packages
+\usepackage[top=2cm,bottom=2cm,left=1.5cm,right=1.5cm]{geometry}
+\usepackage{float}
+\usepackage{dbk_core}
+\usepackage{dbk_admonition}
+\usepackage{fancyvrb}
+
+% Text layout
+\setlength\parskip{\medskipamount}
+\setlength\parindent{0pt}
+\raggedbottom
+
+% Stuff we don't need
+\def\DBKinditem#1#2{}
+\newenvironment{DBKindtable}{}{}
+\newenvironment{DBKrevtable}{}{}
+\newenvironment{DBKlegalnotice}{}{}
+
+% Admonitions
+\floatstyle{boxed}
+\newfloat{DBKadmonition}{h}{lop}
+\newfloat{sidebar}{h}{lop}
+
+% Page break before sections
+\let\orig@section\section
+\renewcommand\section{
+ \clearpage\orig@section
+}
+
+% Ensure line break after paragraph heading
+\renewcommand\paragraph{%
+ \@startsection{paragraph}{4}{\z@}%
+ {-2.25ex\@plus -1ex \@minus -.2ex}%
+ {0.5ex \@plus .2ex}%
+ {\normalfont\normalsize\bfseries}%
+}
+
+% Add page numbers to hyperlinks
+%\let\orig@hyperlink\hyperlink
+%\renewcommand{\hyperlink}[2]{
+% \orig@hyperlink{#1}{#2} (page \pageref{#1})
+%}
+
+% Extra indent on TOC section numbers
+\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{3.3em}}
+\renewcommand*\l@subsubsection{\@dottedtocline{3}{3.8em}{4.2em}}
+\renewcommand*\l@paragraph{\@dottedtocline{4}{7.0em}{5.1em}}
+
+% Title page
+\renewcommand\maketitle{
+ \null
+ \thispagestyle{empty}
+ \begin{center}
+ \null\vskip 7cm
+ \begin{LARGE}
+ asio C++ library
+ \end{LARGE}
+ \null\vskip 1cm
+ \begin{large}
+ \DBKsubtitle{}
+ \end{large}
+ \null\vskip 1cm
+ \begin{Large}
+ Reference Manual
+ \end{Large}
+ \null\vskip 5cm
+ \begin{small}
+ \DBKcopyright{}
+ \end{small}
+ \end{center}
+ \vfill
+ \null
+ \cleardoublepage
+}
diff --git a/3rdparty/asio/src/doc/asioref.xsl b/3rdparty/asio/src/doc/asioref.xsl
new file mode 100644
index 00000000000..09c6fefa45b
--- /dev/null
+++ b/3rdparty/asio/src/doc/asioref.xsl
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ Copyright (c) 2003-2016 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)
+-->
+
+<xsl:output method="xml"/>
+<xsl:strip-space elements="title"/>
+
+<xsl:param name="asio.version">X.Y.Z</xsl:param>
+
+<xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="blockquote/para">
+ <xsl:apply-templates select="para"/>
+</xsl:template>
+
+<xsl:template match="title/link">
+ <xsl:value-of select="normalize-space(.)"/>
+</xsl:template>
+
+<xsl:template match="bridgehead[count(link) &gt; 0]">
+ <xsl:element name="bridgehead">
+ <xsl:attribute name="renderas">
+ <xsl:value-of select="@renderas"/>
+ </xsl:attribute>
+ <xsl:value-of select="normalize-space(link)"/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="chapter">
+ <article id="asio" name="Asio Reference Manual" dirname="asio">
+ <xsl:apply-templates select="chapterinfo"/>
+ <title>Asio Reference Manual</title>
+ <xsl:apply-templates select="section"/>
+ </article>
+</xsl:template>
+
+<xsl:template match="chapterinfo">
+ <articleinfo>
+ <xsl:apply-templates select="*"/>
+ <subtitle><xsl:value-of select="$asio.version"/></subtitle>
+ </articleinfo>
+</xsl:template>
+
+<xsl:template match="section[@id='asio.reference']/informaltable">
+ <xsl:element name="informaltable">
+ <xsl:attribute name="role">scriptsize</xsl:attribute>
+ <xsl:apply-templates select="*"/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="section[@id='asio.examples']/*/listitem">
+ <xsl:element name="listitem">
+ <xsl:value-of select="substring-after(normalize-space(ulink), '../')"/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="imagedata">
+ <xsl:element name="imagedata">
+ <xsl:attribute name="fileref">
+ <xsl:value-of select="@fileref"/>
+ </xsl:attribute>
+ <xsl:attribute name="scale">75</xsl:attribute>
+ <xsl:attribute name="align">center</xsl:attribute>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="programlisting/phrase">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="programlisting/link">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="programlisting/emphasis">
+ <xsl:if test="not(contains(., 'more...'))">
+ <emphasis><xsl:apply-templates/></emphasis>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="section[@id='asio.index']"></xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/3rdparty/asio/src/doc/boost_bind_dox.txt b/3rdparty/asio/src/doc/boost_bind_dox.txt
new file mode 100644
index 00000000000..19c635d951a
--- /dev/null
+++ b/3rdparty/asio/src/doc/boost_bind_dox.txt
@@ -0,0 +1,5 @@
+/**
+\page boost_bind boost::bind
+See the <a href="http://www.boost.org/libs/bind/bind.html">Boost: bind.hpp
+documentation</a> for more information on how to use <tt>boost::bind</tt>.
+*/
diff --git a/3rdparty/asio/src/doc/doxy2qbk.pl b/3rdparty/asio/src/doc/doxy2qbk.pl
new file mode 100644
index 00000000000..9e4e2a2b387
--- /dev/null
+++ b/3rdparty/asio/src/doc/doxy2qbk.pl
@@ -0,0 +1,22 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2003-2016 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)
+
+use strict;
+
+system("doxygen reference.dox");
+chdir("xml");
+system("xsltproc combine.xslt index.xml > all.xml");
+chdir("..");
+system("xsltproc reference.xsl xml/all.xml > reference.qbk");
+system("rm -rf xml");
+
+system("doxygen tutorial.dox");
+chdir("xml");
+system("xsltproc combine.xslt index.xml > all.xml");
+chdir("..");
+system("xsltproc tutorial.xsl xml/all.xml > tutorial.qbk");
+system("rm -rf xml reference.tags");
diff --git a/3rdparty/asio/src/doc/examples.qbk b/3rdparty/asio/src/doc/examples.qbk
new file mode 100644
index 00000000000..17310eef7fa
--- /dev/null
+++ b/3rdparty/asio/src/doc/examples.qbk
@@ -0,0 +1,419 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:examples Examples]
+
+
+* [link asio.examples.cpp03_examples C++03 Examples]: Illustrates the use of
+Asio using only C++03 language and library features. Where necessary, the
+examples make use of selected Boost C++ libraries.
+
+* [link asio.examples.cpp11_examples C++11 Examples]: Contains a limited set of
+the C++03 Asio examples, updated to use only C++11 library and language
+facilities. These examples do not make direct use of Boost C++ libraries.
+[/boostify: non-boost docs start here]
+To show the changes between C++03 and C++11, these examples include a diff
+between the C++03 and C++11 versions.
+[/boostify: non-boost docs end here]
+
+
+[section:cpp03_examples C++03 Examples]
+
+
+[heading Allocation]
+
+This example shows how to customise the allocation of memory associated with
+asynchronous operations.
+
+* [@../src/examples/cpp03/allocation/server.cpp]
+
+
+[heading Buffers]
+
+This example demonstrates how to create reference counted buffers that can be
+used with socket read and write operations.
+
+* [@../src/examples/cpp03/buffers/reference_counted.cpp]
+
+
+[heading Chat]
+
+This example implements a chat server and client. The programs use a custom
+protocol with a fixed length message header and variable length message body.
+
+* [@../src/examples/cpp03/chat/chat_message.hpp]
+* [@../src/examples/cpp03/chat/chat_client.cpp]
+* [@../src/examples/cpp03/chat/chat_server.cpp]
+
+The following POSIX-specific chat client demonstrates how to use the
+[link asio.reference.posix__stream_descriptor posix::stream_descriptor] class to
+perform console input and output.
+
+* [@../src/examples/cpp03/chat/posix_chat_client.cpp]
+
+
+[heading Echo]
+
+A collection of simple clients and servers, showing the use of both synchronous
+and asynchronous operations.
+
+* [@../src/examples/cpp03/echo/async_tcp_echo_server.cpp]
+* [@../src/examples/cpp03/echo/async_udp_echo_server.cpp]
+* [@../src/examples/cpp03/echo/blocking_tcp_echo_client.cpp]
+* [@../src/examples/cpp03/echo/blocking_tcp_echo_server.cpp]
+* [@../src/examples/cpp03/echo/blocking_udp_echo_client.cpp]
+* [@../src/examples/cpp03/echo/blocking_udp_echo_server.cpp]
+
+
+[heading Fork]
+
+These POSIX-specific examples show how to use Asio in conjunction with the
+`fork()` system call. The first example illustrates the steps required to start
+a daemon process:
+
+* [@../src/examples/cpp03/fork/daemon.cpp]
+
+The second example demonstrates how it is possible to fork a process from
+within a completion handler.
+
+* [@../src/examples/cpp03/fork/process_per_connection.cpp]
+
+
+[heading HTTP Client]
+
+Example programs implementing simple HTTP 1.0 clients. These examples show how
+to use the [link asio.reference.read_until read_until] and [link
+asio.reference.async_read_until async_read_until] functions.
+
+* [@../src/examples/cpp03/http/client/sync_client.cpp]
+* [@../src/examples/cpp03/http/client/async_client.cpp]
+
+
+[heading HTTP Server]
+
+This example illustrates the use of asio in a simple single-threaded server
+implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown by
+cancelling all outstanding asynchronous operations.
+
+* [@../src/examples/cpp03/http/server/connection.cpp]
+* [@../src/examples/cpp03/http/server/connection.hpp]
+* [@../src/examples/cpp03/http/server/connection_manager.cpp]
+* [@../src/examples/cpp03/http/server/connection_manager.hpp]
+* [@../src/examples/cpp03/http/server/header.hpp]
+* [@../src/examples/cpp03/http/server/main.cpp]
+* [@../src/examples/cpp03/http/server/mime_types.cpp]
+* [@../src/examples/cpp03/http/server/mime_types.hpp]
+* [@../src/examples/cpp03/http/server/reply.cpp]
+* [@../src/examples/cpp03/http/server/reply.hpp]
+* [@../src/examples/cpp03/http/server/request.hpp]
+* [@../src/examples/cpp03/http/server/request_handler.cpp]
+* [@../src/examples/cpp03/http/server/request_handler.hpp]
+* [@../src/examples/cpp03/http/server/request_parser.cpp]
+* [@../src/examples/cpp03/http/server/request_parser.hpp]
+* [@../src/examples/cpp03/http/server/server.cpp]
+* [@../src/examples/cpp03/http/server/server.hpp]
+
+
+[heading HTTP Server 2]
+
+An HTTP server using an io_context-per-CPU design.
+
+* [@../src/examples/cpp03/http/server2/connection.cpp]
+* [@../src/examples/cpp03/http/server2/connection.hpp]
+* [@../src/examples/cpp03/http/server2/header.hpp]
+* [@../src/examples/cpp03/http/server2/io_context_pool.cpp]
+* [@../src/examples/cpp03/http/server2/io_context_pool.hpp]
+* [@../src/examples/cpp03/http/server2/main.cpp]
+* [@../src/examples/cpp03/http/server2/mime_types.cpp]
+* [@../src/examples/cpp03/http/server2/mime_types.hpp]
+* [@../src/examples/cpp03/http/server2/reply.cpp]
+* [@../src/examples/cpp03/http/server2/reply.hpp]
+* [@../src/examples/cpp03/http/server2/request.hpp]
+* [@../src/examples/cpp03/http/server2/request_handler.cpp]
+* [@../src/examples/cpp03/http/server2/request_handler.hpp]
+* [@../src/examples/cpp03/http/server2/request_parser.cpp]
+* [@../src/examples/cpp03/http/server2/request_parser.hpp]
+* [@../src/examples/cpp03/http/server2/server.cpp]
+* [@../src/examples/cpp03/http/server2/server.hpp]
+
+
+[heading HTTP Server 3]
+
+An HTTP server using a single io_context and a thread pool calling `io_context::run()`.
+
+* [@../src/examples/cpp03/http/server3/connection.cpp]
+* [@../src/examples/cpp03/http/server3/connection.hpp]
+* [@../src/examples/cpp03/http/server3/header.hpp]
+* [@../src/examples/cpp03/http/server3/main.cpp]
+* [@../src/examples/cpp03/http/server3/mime_types.cpp]
+* [@../src/examples/cpp03/http/server3/mime_types.hpp]
+* [@../src/examples/cpp03/http/server3/reply.cpp]
+* [@../src/examples/cpp03/http/server3/reply.hpp]
+* [@../src/examples/cpp03/http/server3/request.hpp]
+* [@../src/examples/cpp03/http/server3/request_handler.cpp]
+* [@../src/examples/cpp03/http/server3/request_handler.hpp]
+* [@../src/examples/cpp03/http/server3/request_parser.cpp]
+* [@../src/examples/cpp03/http/server3/request_parser.hpp]
+* [@../src/examples/cpp03/http/server3/server.cpp]
+* [@../src/examples/cpp03/http/server3/server.hpp]
+
+
+[heading HTTP Server 4]
+
+A single-threaded HTTP server implemented using stackless coroutines.
+
+* [@../src/examples/cpp03/http/server4/file_handler.cpp]
+* [@../src/examples/cpp03/http/server4/file_handler.hpp]
+* [@../src/examples/cpp03/http/server4/header.hpp]
+* [@../src/examples/cpp03/http/server4/main.cpp]
+* [@../src/examples/cpp03/http/server4/mime_types.cpp]
+* [@../src/examples/cpp03/http/server4/mime_types.hpp]
+* [@../src/examples/cpp03/http/server4/reply.cpp]
+* [@../src/examples/cpp03/http/server4/reply.hpp]
+* [@../src/examples/cpp03/http/server4/request.hpp]
+* [@../src/examples/cpp03/http/server4/request_parser.cpp]
+* [@../src/examples/cpp03/http/server4/request_parser.hpp]
+* [@../src/examples/cpp03/http/server4/server.cpp]
+* [@../src/examples/cpp03/http/server4/server.hpp]
+
+
+[heading ICMP]
+
+This example shows how to use raw sockets with ICMP to ping a remote host.
+
+* [@../src/examples/cpp03/icmp/ping.cpp]
+* [@../src/examples/cpp03/icmp/ipv4_header.hpp]
+* [@../src/examples/cpp03/icmp/icmp_header.hpp]
+
+
+[heading Invocation]
+
+This example shows how to customise handler invocation. Completion handlers are
+added to a priority queue rather than executed immediately.
+
+* [@../src/examples/cpp03/invocation/prioritised_handlers.cpp]
+
+
+[heading Iostreams]
+
+Two examples showing how to use [link asio.reference.ip__tcp.iostream
+ip::tcp::iostream].
+
+* [@../src/examples/cpp03/iostreams/daytime_client.cpp]
+* [@../src/examples/cpp03/iostreams/daytime_server.cpp]
+* [@../src/examples/cpp03/iostreams/http_client.cpp]
+
+
+[heading Multicast]
+
+An example showing the use of multicast to transmit packets to a group of
+subscribers.
+
+* [@../src/examples/cpp03/multicast/receiver.cpp]
+* [@../src/examples/cpp03/multicast/sender.cpp]
+
+
+[heading Serialization]
+
+This example shows how Boost.Serialization can be used with asio to encode and
+decode structures for transmission over a socket.
+
+* [@../src/examples/cpp03/serialization/client.cpp]
+* [@../src/examples/cpp03/serialization/connection.hpp]
+* [@../src/examples/cpp03/serialization/server.cpp]
+* [@../src/examples/cpp03/serialization/stock.hpp]
+
+
+[heading Services]
+
+This example demonstrates how to integrate custom functionality (in this case,
+for logging) into asio's [link asio.reference.io_context io_context], and
+how to use a custom service with [link
+asio.reference.basic_stream_socket basic_stream_socket<>].
+
+* [@../src/examples/cpp03/services/basic_logger.hpp]
+* [@../src/examples/cpp03/services/daytime_client.cpp]
+* [@../src/examples/cpp03/services/logger.hpp]
+* [@../src/examples/cpp03/services/logger_service.cpp]
+* [@../src/examples/cpp03/services/logger_service.hpp]
+* [@../src/examples/cpp03/services/stream_socket_service.hpp]
+
+
+[heading SOCKS 4]
+
+Example client program implementing the SOCKS 4 protocol for communication via
+a proxy.
+
+* [@../src/examples/cpp03/socks4/sync_client.cpp]
+* [@../src/examples/cpp03/socks4/socks4.hpp]
+
+
+[heading SSL]
+
+Example client and server programs showing the use of the [link
+asio.reference.ssl__stream ssl::stream<>] template with asynchronous operations.
+
+* [@../src/examples/cpp03/ssl/client.cpp]
+* [@../src/examples/cpp03/ssl/server.cpp]
+
+
+[heading Timeouts]
+
+A collection of examples showing how to cancel long running asynchronous
+operations after a period of time.
+
+* [@../src/examples/cpp03/timeouts/async_tcp_client.cpp]
+* [@../src/examples/cpp03/timeouts/blocking_tcp_client.cpp]
+* [@../src/examples/cpp03/timeouts/blocking_udp_client.cpp]
+* [@../src/examples/cpp03/timeouts/server.cpp]
+
+
+[heading Timers]
+
+Examples showing how to customise deadline_timer using different time types.
+
+* [@../src/examples/cpp03/timers/tick_count_timer.cpp]
+* [@../src/examples/cpp03/timers/time_t_timer.cpp]
+
+
+[heading Porthopper]
+
+Example illustrating mixed synchronous and asynchronous operations, and how to
+use Boost.Lambda with Asio.
+
+* [@../src/examples/cpp03/porthopper/protocol.hpp]
+* [@../src/examples/cpp03/porthopper/client.cpp]
+* [@../src/examples/cpp03/porthopper/server.cpp]
+
+
+[heading Nonblocking]
+
+Example demonstrating reactor-style operations for integrating a third-party
+library that wants to perform the I/O operations itself.
+
+* [@../src/examples/cpp03/nonblocking/third_party_lib.cpp]
+
+
+[heading Spawn]
+
+Example of using the asio::spawn() function, a wrapper around the
+[@http://www.boost.org/doc/libs/release/libs/coroutine/index.html Boost.Coroutine]
+library, to implement a chain of asynchronous operations using stackful
+coroutines.
+
+* [@../src/examples/cpp03/spawn/echo_server.cpp]
+
+
+[heading UNIX Domain Sockets]
+
+Examples showing how to use UNIX domain (local) sockets.
+
+* [@../src/examples/cpp03/local/connect_pair.cpp]
+* [@../src/examples/cpp03/local/stream_server.cpp]
+* [@../src/examples/cpp03/local/stream_client.cpp]
+
+
+[heading Windows]
+
+An example showing how to use the Windows-specific function `TransmitFile`
+with Asio.
+
+* [@../src/examples/cpp03/windows/transmit_file.cpp]
+
+
+[endsect]
+
+
+[section:cpp11_examples C++11 Examples]
+
+
+[heading Allocation]
+
+This example shows how to customise the allocation of memory associated with
+asynchronous operations.
+
+* [@../src/examples/cpp11/allocation/server.cpp] ([@examples/diffs/allocation/server.cpp.html diff to C++03])
+
+
+[heading Buffers]
+
+This example demonstrates how to create reference counted buffers that can be
+used with socket read and write operations.
+
+* [@../src/examples/cpp11/buffers/reference_counted.cpp] ([@examples/diffs/buffers/reference_counted.cpp.html diff to C++03])
+
+
+[heading Chat]
+
+This example implements a chat server and client. The programs use a custom
+protocol with a fixed length message header and variable length message body.
+
+* [@../src/examples/cpp11/chat/chat_message.hpp] ([@examples/diffs/chat/chat_message.hpp.html diff to C++03])
+* [@../src/examples/cpp11/chat/chat_client.cpp] ([@examples/diffs/chat/chat_client.cpp.html diff to C++03])
+* [@../src/examples/cpp11/chat/chat_server.cpp] ([@examples/diffs/chat/chat_server.cpp.html diff to C++03])
+
+
+[heading Echo]
+
+A collection of simple clients and servers, showing the use of both synchronous
+and asynchronous operations.
+
+* [@../src/examples/cpp11/echo/async_tcp_echo_server.cpp] ([@examples/diffs/echo/async_tcp_echo_server.cpp.html diff to C++03])
+* [@../src/examples/cpp11/echo/async_udp_echo_server.cpp] ([@examples/diffs/echo/async_udp_echo_server.cpp.html diff to C++03])
+* [@../src/examples/cpp11/echo/blocking_tcp_echo_client.cpp] ([@examples/diffs/echo/blocking_tcp_echo_client.cpp.html diff to C++03])
+* [@../src/examples/cpp11/echo/blocking_tcp_echo_server.cpp] ([@examples/diffs/echo/blocking_tcp_echo_server.cpp.html diff to C++03])
+* [@../src/examples/cpp11/echo/blocking_udp_echo_client.cpp] ([@examples/diffs/echo/blocking_udp_echo_client.cpp.html diff to C++03])
+* [@../src/examples/cpp11/echo/blocking_udp_echo_server.cpp] ([@examples/diffs/echo/blocking_udp_echo_server.cpp.html diff to C++03])
+
+
+[heading Futures]
+
+This example demonstrates how to use std::future in conjunction with
+Asio's asynchronous operations.
+
+* [@../src/examples/cpp11/futures/daytime_client.cpp]
+
+
+[heading HTTP Server]
+
+This example illustrates the use of asio in a simple single-threaded server
+implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown by
+cancelling all outstanding asynchronous operations.
+
+* [@../src/examples/cpp11/http/server/connection.cpp] ([@examples/diffs/http/server/connection.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/connection.hpp] ([@examples/diffs/http/server/connection.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/connection_manager.cpp] ([@examples/diffs/http/server/connection_manager.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/connection_manager.hpp] ([@examples/diffs/http/server/connection_manager.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/header.hpp] ([@examples/diffs/http/server/header.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/main.cpp] ([@examples/diffs/http/server/main.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/mime_types.cpp] ([@examples/diffs/http/server/mime_types.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/mime_types.hpp] ([@examples/diffs/http/server/mime_types.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/reply.cpp] ([@examples/diffs/http/server/reply.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/reply.hpp] ([@examples/diffs/http/server/reply.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/request.hpp] ([@examples/diffs/http/server/request.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/request_handler.cpp] ([@examples/diffs/http/server/request_handler.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/request_handler.hpp] ([@examples/diffs/http/server/request_handler.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/request_parser.cpp] ([@examples/diffs/http/server/request_parser.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/request_parser.hpp] ([@examples/diffs/http/server/request_parser.hpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/server.cpp] ([@examples/diffs/http/server/server.cpp.html diff to C++03])
+* [@../src/examples/cpp11/http/server/server.hpp] ([@examples/diffs/http/server/server.hpp.html diff to C++03])
+
+
+[heading Spawn]
+
+Example of using the asio::spawn() function, a wrapper around the
+[@http://www.boost.org/doc/libs/release/libs/coroutine/index.html Boost.Coroutine]
+library, to implement a chain of asynchronous operations using stackful
+coroutines.
+
+* [@../src/examples/cpp11/spawn/echo_server.cpp] ([@examples/diffs/spawn/echo_server.cpp.html diff to C++03])
+
+
+[endsect]
+
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/history.qbk b/3rdparty/asio/src/doc/history.qbk
new file mode 100644
index 00000000000..e5c3ddbeb80
--- /dev/null
+++ b/3rdparty/asio/src/doc/history.qbk
@@ -0,0 +1,1214 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:history Revision History]
+
+[heading Asio 1.11.0]
+
+* Implemented changes to substantially reflect the Networking Library Proposal
+ ([@www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html N4370]).
+
+ * New `Executor` type requirements and classes to support an executor
+ framework, including the `execution_context` base class, the
+ `executor_work` class for tracking outstanding work, and the `executor`
+ polymorphic wrapper. Free functions `dispatch()`, `post()` and `defer()`
+ have been added and are used to submit function objects to executors.
+
+ * Completion handlers now have an associated executor and associated
+ allocator. The free function `wrap()` is used to associate an executor with
+ a handler or other object. The handler hooks for allocation, invocation and
+ continuation have been deprecated.
+
+ * A `system_executor` class has been added as a default executor.
+
+ * The `io_service` class is now derived from `execution_context` and
+ implements the executor type requirements in its nested `executor_type`
+ class. The member functions `dispatch()`, `post()`, `defer()` and `wrap()`
+ have been deprecated. The `io_service::work` class has been deprecated.
+
+ * The `io_service` member function `reset()` has been renamed to `restart()`.
+ The old name is retained for backward compatibility but has been
+ deprecated.
+
+ * The `make_service<>()` function is now used to add a new service to an
+ execution context such as an `io_service`. The `add_service()` function has
+ been deprecated.
+
+ * A new `strand<>` template has been added to allow strand functionality to
+ be used with generic executor types.
+
+ * I/O objects (such as sockets and timers) now provide access to their
+ associated `io_service` via a `context()` member function. The
+ `get_io_service()` member function is deprecated.
+
+ * All asynchronous operations and executor operations now support move-only
+ handlers. However, the deprecated `io_service::post()`,
+ `io_service::dispatch()`, `io_service::strand::post()` and
+ `io_service::strand::dispatch()` functions still require copyable handlers.
+
+ * Waitable timer objects are now movable.
+
+ * Waitable timers, socket iostreams and socket streambufs now provide an
+ `expiry()` member function for obtaining the expiry time. The accessors
+ `expires_at()` and `expires_after()` have been deprecated, though those
+ names are retained for the mutating members.
+
+ * The `std::packaged_task` class template is now supported as a completion
+ handler. The initiating operation automatically returns the future
+ associated with the task. The `package()` function has been added as a
+ convenient factory for packaged tasks.
+
+ * Sockets, socket acceptors and descriptors now provide `wait()` and
+ `async_wait()` operations that may be used to wait for readiness. The
+ `null_buffers` type has been deprecated.
+
+ * The proposed error code enum classes are simulated using namespaces.
+ Existing asio error codes now have a correspondence with the standard error
+ conditions.
+
+ * Conversion between IP address types, and conversion from string to address,
+ is now supported via the `address_cast<>()`, `make_address()`,
+ `make_address_v4()` and `make_address_v6()` free functions. The
+ `from_string()`, `to_v4()`, `to_v6()` and `v4_mapped()` member functions
+ have been deprecated.
+
+ * A default-constructed `ip::address` now represents an invalid address value
+ that is neither IPv4 nor IPv6.
+
+ * New `buffer()` overloads that generate mutable buffers for non-const
+ `string` objects.
+
+ * Support for dynamic buffer sequences that automatically grow and shrink to
+ accomodate data as it is read or written. This is a generic facility
+ similar to the existing `asio::streambuf` class. This support includes:
+
+ * New `dynamic_string_buffer` and `dynamic_vector_buffer` adapter classes
+ that meet the `DynamicBufferSequence` type requirements.
+
+ * New `dynamic_buffer()` factory functions for creating a dynamic buffer
+ adapter for a `vector` or `string`.
+
+ * New overloads for the `read()`, `async_read()`, `write()` and
+ `async_write()`, `read_until()` and `async_read_until()` free functions
+ that directly support dynamic buffer sequences.
+
+ * Support for networks and address ranges. Thanks go to Oliver Kowalke for
+ contributing to the design and providing the implementation on which this
+ facility is based. The following new classes have been added:
+
+ * `address_iterator_v4` for iterating across IPv4 addresses
+ * `address_iterator_v6` for iterating across IPv6 addresses
+ * `address_range_v4` to represent a range of IPv4 addresses
+ * `address_range_v6` to represent a range of IPv6 addresses
+ * `network_v4` for manipulating IPv4 CIDR addresses, e.g. 1.2.3.0/24
+ * `network_v6` for manipulating IPv6 CIDR addresses, e.g. ffe0:/120
+
+ * New convenience headers in [^<asio/ts/*.hpp>] that correspond to the headers
+ in the proposal.
+
+* Added a new, executor-aware `thread_pool` class.
+
+* Changed `spawn()` to be executor-aware.
+
+* Added a new `spawn()` overload that takes only a function object.
+
+* Changed `spawn()` and `yield_context` to permit nested calls to the
+ completion handler.
+
+* Removed previously deprecated functions.
+
+* Added options for disabling TLS v1.1 and v1.2.
+
+* Changed the SSL wrapper to call the password callback when loading an
+ in-memory key.
+
+* Changed the tutorial to use `std::endl` to ensure output is flushed.
+
+* Fixed false SSL error reports by ensuring that the SSL error queue is cleared
+ prior to each operation.
+
+* Fixed an `ssl::stream<>` bug that may result in spurious 'short read' errors.
+
+* Enabled perfect forwarding for the first `ssl::stream<>` constructor argument.
+
+* Added standalone Asio support for Clang when used with libstdc++ and C++11.
+
+* Fixed an unsigned integer overflow reported by Clang's integer sanitizer.
+
+* Added support for move-only return types when using a `yield_context` object
+ with asynchronous operations.
+
+* Ensured errors generated by Windows' `ConnectEx` function are mapped to their
+ portable equivalents.
+
+* Changed multicast test to treat certain `join_group` failures as non-fatal.
+
+[heading Asio 1.10.5]
+
+* Fixed the [^kqueue] reactor so that it works on FreeBSD.
+
+* Fixed an issue in the [^kqueue] reactor which resulted in spinning when using
+ serial ports on Mac OS.
+
+* Fixed [^kqueue] reactor support for read-only file descriptors.
+
+* Fixed a compile error when using the [^/dev/poll] reactor.
+
+* Changed the Windows backend to use `WSASocketW`, as `WSASocketA` has been
+ deprecated.
+
+* Fixed some warnings reported by Visual C++ 2013.
+
+* Fixed integer type used in the WinRT version of the byte-order conversion
+ functions.
+
+* Changed documentation to indicate that `use_future` and `spawn()` are not
+ made available when including the `asio.hpp` convenience header.
+
+* Explicitly marked `asio::strand` as deprecated. Use
+ `asio::io_service::strand` instead.
+
+[heading Asio 1.10.4]
+
+* Stopped using certain Winsock functions that are marked as deprecated in the
+ latest Visual C++ and Windows SDK.
+
+* Fixed a shadow variable warning on Windows.
+
+* Fixed a regression in the [^kqueue] backend that was introduced in Asio
+ 1.10.2.
+
+* Added a workaround for building the unit tests with [^gcc] on AIX.
+
+[heading Asio 1.10.3]
+
+* Worked around a [^gcc] problem to do with anonymous enums.
+
+* Reverted the Windows `HANDLE` backend change to ignore `ERROR_MORE_DATA`.
+ Instead, the error will be propagated as with any other (i.e. in an
+ `error_code` or thrown as a `system_error`), and the number of bytes
+ transferred will be returned. For code that needs to handle partial messages,
+ the `error_code` overload should be used.
+
+* Fixed an off-by-one error in the `signal_set` implementation's signal
+ number check.
+
+* Changed the Windows IOCP backend to not assume that
+ `SO_UPDATE_CONNECT_CONTEXT` is defined.
+
+* Fixed a Windows-specific issue, introduced in Asio 1.10.2, by using
+ `VerifyVersionInfo` rather than `GetVersionEx`, as `GetVersionEx` has been
+ deprecated.
+
+* Changed to use SSE2 intrinsics rather than inline assembly, to allow the
+ Cray compiler to work.
+
+[heading Asio 1.10.2]
+
+* Fixed `asio::spawn()` to work correctly with new Boost.Coroutine interface.
+
+* Ensured that incomplete `asio::spawn()` coroutines are correctly unwound when
+ cleaned up by the `io_service` destructor.
+
+* Fixed delegation of continuation hook for handlers produced by
+ `io_service::wrap()` and `strand::wrap()`.
+
+* Changed the Windows I/O completion port backend to use `ConnectEx`, if
+ available, for connection-oriented IP sockets.
+
+* Changed the `io_service` backend for non-Windows (and non-IOCP Windows)
+ platforms to use a single condition variable per `io_service` instance.
+ This addresses a potential race condition when `run_one()` is used from
+ multiple threads.
+
+* Prevented integer overflow when computing timeouts based on some
+ `boost::chrono` and `std::chrono` clocks.
+
+* Made further changes to `EV_CLEAR` handling in the kqueue backend, to address
+ other cases where the `close()` system call may hang on Mac OS X.
+
+* Fixed infinite recursion in implementation of
+ `resolver_query_base::flags::operator~`.
+
+* Made the `select` reactor more efficient on Windows for large numbers of
+ sockets.
+
+* Fixed a Windows-specific type-aliasing issue reported by [^gcc].
+
+* Prevented execution of compile-time-only buffer test to avoid triggering an
+ address sanitiser warning.
+
+* Disabled the `GetQueuedCompletionStatus` timeout workaround on recent
+ versions of Windows.
+
+* Changed implementation for Windows Runtime to use `FormatMessageW` rather
+ than `FormatMessageA`, as the Windows store does not permit the latter.
+
+* Added support for string-based scope IDs when using link-local multicast
+ addresses.
+
+* Changed IPv6 multicast group join to use the address's scope ID as the
+ interface, if an interface is not explicitly specified.
+
+* Fixed multicast test failure on Mac OS X and the BSDs by using a link-local
+ multicast address.
+
+* Various minor documentation improvements.
+
+[heading Asio 1.10.1]
+
+* Implemented a limited port to Windows Runtime. This support requires that the
+ language extensions be enabled. Due to the restricted facilities exposed by
+ the Windows Runtime API, the port also comes with the following caveats:
+
+ * The core facilities such as the `io_service`, `strand`, buffers, composed
+ operations, timers, etc., should all work as normal.
+
+ * For sockets, only client-side TCP is supported.
+
+ * Explicit binding of a client-side TCP socket is not supported.
+
+ * The `cancel()` function is not supported for sockets. Asynchronous
+ operations may only be cancelled by closing the socket.
+
+ * Operations that use `null_buffers` are not supported.
+
+ * Only `tcp::no_delay` and `socket_base::keep_alive` options are supported.
+
+ * Resolvers do not support service names, only numbers. I.e. you must
+ use "80" rather than "http".
+
+ * Most resolver query flags have no effect.
+
+* Extended the ability to use Asio without Boost to include Microsoft Visual
+ Studio 2012. When using a C++11 compiler, most of Asio may now be used
+ without a dependency on Boost header files or libraries. To use Asio in this
+ way, define `ASIO_STANDALONE` on your compiler command line or as part of the
+ project options. This standalone configuration has been tested for the
+ following platforms and compilers:
+
+ * Microsoft Visual Studio 2012
+
+ * Linux with g++ 4.7 or 4.8 (requires [^-std=c++11])
+
+ * Mac OS X with clang++ / Xcode 4.6 (requires [^-std=c++11 -stdlib=libc++])
+
+* Fixed a regression (introduced in 1.10.0) where, on some platforms, errors
+ from `async_connect` were not correctly propagated through to the completion
+ handler.
+
+* Fixed a Windows-specific regression (introduced in 1.10.0) that occurs when
+ multiple threads are running an `io_service`. When the bug occurs, the result
+ of an asynchronous operation (error and bytes tranferred) is incorrectly
+ discarded and zero values used instead. For TCP sockets this results in
+ spurious end-of-file notifications.
+
+* Fixed a bug in handler tracking, where it was not correctly printing out some
+ handler IDs.
+
+* Fixed the comparison used to test for successful synchronous accept
+ operations so that it works correctly with unsigned socket descriptors.
+
+* Ensured the signal number is correctly passed to the completion handler when
+ starting an `async_wait` on a signal that is already raised.
+
+* Suppressed a g++ 4.8+ warning about unused typedefs.
+
+* Enabled the move optimisation for handlers that use the default invocation
+ hook.
+
+* Clarified that programs must not issue overlapping `async_write_at`
+ operations.
+
+* Changed the Windows `HANDLE` backend to treat `ERROR_MORE_DATA` as a
+ non-fatal error when returned by `GetOverlappedResult` for a synchronous
+ read.
+
+* Visual C++ language extensions use `generic` as a keyword. Added a
+ workaround that renames the namespace to `cpp_generic` when those language
+ extensions are in effect.
+
+* Fixed some asynchronous operations that missed out on getting `async_result`
+ support in 1.10.0. In particular, the buffered stream templates have been
+ updated so that they adhere to current handler patterns.
+
+* Enabled move support for Microsoft Visual Studio 2012.
+
+* Added `use_future` support for Microsoft Visual Studio 2012.
+
+* Removed a use of `std::min` in the Windows IOCP backend to avoid a
+ dependency on the `<algorithm>` header.
+
+* Eliminated some unnecessary handler copies.
+
+* Fixed support for older versions of OpenSSL that do not provide the
+ `SSL_CTX_clear_options` function.
+
+* Fixed various minor and cosmetic issues in code and documentation.
+
+[heading Asio 1.10.0]
+
+* Added new traits classes, `handler_type` and `async_result`, that allow the
+ customisation of the return type of an initiating function.
+
+* Added the `asio::spawn()` function, a high-level wrapper for running
+ stackful coroutines, based on the Boost.Coroutine library. The `spawn()`
+ function enables programs to implement asynchronous logic in a synchronous
+ manner. For example: `size_t n = my_socket.async_read_some(my_buffer, yield);`.
+ For further information, see [link asio.overview.core.spawn Stackful
+ Coroutines].
+
+* Added the `asio::use_future` special value, which provides first-class
+ support for returning a C++11 `std::future` from an asynchronous
+ operation's initiating function. For example:
+ `future<size_t> = my_socket.async_read_some(my_buffer, asio::use_future);`.
+ For further information, see [link asio.overview.cpp2011.futures C++
+ 2011 Support - Futures].
+
+* Promoted the stackless coroutine class and macros to be part of Asio's
+ documented interface, rather than part of the HTTP server 4 example.
+ For further information, see [link asio.overview.core.coroutine
+ Stackless Coroutines].
+
+* Added a new handler hook called `asio_handler_is_continuation`.
+ Asynchronous operations may represent a continuation of the asynchronous
+ control flow associated with the current executing handler. The
+ `asio_handler_is_continuation` hook can be customised to return `true` if
+ this is the case, and Asio's implementation can use this knowledge to
+ optimise scheduling of the new handler. To cover common cases, Asio
+ customises the hook for strands, `spawn()` and composed asynchronous
+ operations.
+
+* Added four new generic protocol classes, `generic::datagram_protocol`,
+ `generic::raw_protocol`, `generic::seq_packet_protocol` and
+ `generic::stream_protocol`, which implement the `Protocol` type
+ requirements, but allow the user to specify the address family (e.g.
+ `AF_INET`) and protocol type (e.g. `IPPROTO_TCP`) at runtime.
+ For further information, see [link
+ asio.overview.networking.other_protocols Support for Other Protocols].
+
+* Added C++11 move constructors that allow the conversion of a socket (or
+ acceptor) into a more generic type. For example, an `ip::tcp::socket` can
+ be converted into a `generic::stream_protocol::socket` via move
+ construction.
+ For further information, see [link
+ asio.overview.networking.other_protocols Support for Other Protocols].
+
+* Extended the `basic_socket_acceptor<>`'s `accept()` and `async_accept()`
+ functions to allow a new connection to be accepted directly into a socket
+ of a more generic type. For example, an `ip::tcp::acceptor` can be used to
+ accept into a `generic::stream_protocol::socket` object.
+ For further information, see [link
+ asio.overview.networking.other_protocols Support for Other Protocols].
+
+* Moved existing examples into a C++03-specific directory, and added a new
+ directory for C++11-specific examples. A limited subset of the C++03
+ examples have been converted to their C++11 equivalents.
+
+* Add the ability to use Asio without Boost, for a limited set of platforms.
+ When using a C++11 compiler, most of Asio may now be used without a
+ dependency on Boost header files or libraries. To use Asio in this way,
+ define `ASIO_STANDALONE` on your compiler command line or as part of the
+ project options. This standalone configuration has currently been tested for
+ the following platforms and compilers:
+
+ * Linux with g++ 4.7 (requires [^-std=c++11])
+
+ * Mac OS X with clang++ / Xcode 4.6 (requires [^-std=c++11 -stdlib=libc++])
+
+* Various SSL enhancements. Thanks go to Nick Jones, on whose work these changes
+ are based.
+
+ * Added support for SSL handshakes with re-use of data already read from
+ the wire. New overloads of the `ssl::stream<>` class's `handshake()` and
+ `async_handshake()` functions have been added. These accept a
+ `ConstBufferSequence` to be used as initial input to the ssl engine for
+ the handshake procedure.
+
+ * Added support for creation of TLSv1.1 and TLSv1.2 `ssl::context` objects.
+
+ * Added a `set_verify_depth()` function to the `ssl::context` and
+ `ssl::stream<>` classes.
+
+ * Added the ability to load SSL certificate and key data from memory
+ buffers. New functions, `add_certificate_authority()`,
+ `use_certificate()`, `use_certificate_chain()`, `use_private_key()`,
+ `use_rsa_private_key()` and `use_tmp_dh()`, have been added to the
+ `ssl::context` class.
+
+ * Changed `ssl::context` to automatically disable SSL compression by
+ default. To enable, use the new `ssl::context::clear_options()` function,
+ as in `my_context.clear_options(ssl::context::no_compression)`.
+
+* Fixed a potential deadlock in `signal_set` implementation.
+
+* Fixed an error in acceptor example in documentation.
+
+* Fixed copy-paste errors in waitable timer documentation.
+
+* Added assertions to satisfy some code analysis tools.
+
+* Fixed a malformed `#warning` directive.
+
+* Fixed a potential data race in the Linux `epoll` implementation.
+
+* Fixed a Windows-specific bug, where certain operations might generate an
+ `error_code` with an invalid (i.e. `NULL`) `error_category`.
+
+* Fixed `basic_waitable_timer`'s underlying implementation so that it can
+ handle any `time_point` value without overflowing the intermediate duration
+ objects.
+
+* Fixed a problem with lost thread wakeups that can occur when making
+ concurrent calls to `run()` and `poll()` on the same `io_service` object.
+
+* Fixed implementation of asynchronous connect operation so that it can cope
+ with spurious readiness notifications from the reactor.
+
+* Fixed a memory leak in the `ssl::rfc2818_verification` class.
+
+* Added a mechanism for disabling automatic Winsock initialisation. See the
+ header file [^asio/detail/winsock_init.hpp] for details.
+
+[heading Asio 1.8.3]
+
+* Fixed some 64-to-32-bit conversion warnings.
+
+* Fixed various small errors in documentation and comments.
+
+* Fixed an error in the example embedded in `basic_socket::get_option`'s
+ documentation.
+
+* Changed to use `long` rather than `int` for SSL_CTX options, to match OpenSSL.
+
+* Changed to use `_snwprintf` to address a compile error due to the changed
+ `swprintf` signature in recent versions of MinGW.
+
+* Fixed a deadlock that can occur on Windows when shutting down a pool of
+ `io_service` threads due to running out of work.
+
+* Changed UNIX domain socket example to treat errors from `accept` as non-fatal.
+
+* Added a small block recycling optimisation to improve default memory
+ allocation behaviour.
+
+[heading Asio 1.8.2]
+
+* Fixed an incompatibility between `ip::tcp::iostream` and C++11.
+
+* Decorated GCC attribute names with underscores to prevent interaction
+ with user-defined macros.
+
+* Added missing `#include <cctype>`, needed for some versions of MinGW.
+
+* Changed to use [^gcc]'s atomic builtins on ARM CPUs, when available.
+
+* Changed strand destruction to be a no-op, to allow strand objects to be
+ destroyed after their associated `io_service` has been destroyed.
+
+* Added support for some newer versions of glibc which provide the
+ `epoll_create1()` function but always fail with ENOSYS.
+
+* Changed the SSL implementation to throw an exception if SSL engine
+ initialisation fails.
+
+* Fixed another regression in `buffered_write_stream`.
+
+* Implemented various minor performance improvements, primarily targeted at
+ Linux x86 and x86-64 platforms.
+
+[heading Asio 1.8.1]
+
+* Changed the `epoll_reactor` backend to do lazy registration for `EPOLLOUT`
+ events.
+
+* Fixed the `epoll_reactor` handling of out-of-band data, which was broken by
+ an incomplete fix in the last release.
+
+* Changed Asio's SSL wrapper to respect OpenSSL's `OPENSSL_NO_ENGINE` feature
+ test `#define`.
+
+* Fixed `windows::object_handle` so that it works with Windows compilers that
+ support C++11 move semantics (such as [^g++]).
+
+* Improved the performance of strand rescheduling.
+
+* Added support for [^g++] 4.7 when compiling in C++11 mode.
+
+* Fixed a problem where `signal_set` handlers were not being delivered when
+ the `io_service` was constructed with a `concurrency_hint` of 1.
+
+[heading Asio 1.8.0]
+
+* Added a new class template `basic_waitable_timer` based around the C++11 clock
+ type requirements. It may be used with the clocks from the C++11 `<chrono>`
+ library facility or, if those are not available, Boost.Chrono. The typedefs
+ `high_resolution_timer`, `steady_timer` and `system_timer` may be used to
+ create timer objects for the standard clock types.
+
+* Added a new `windows::object_handle` class for performing waits on Windows
+ kernel objects. Thanks go to Boris Schaeling for contributing substantially
+ to the development of this feature.
+
+* On Linux, `connect()` can return EAGAIN in certain circumstances. Remapped
+ this to another error so that it doesn't look like a non-blocking operation.
+
+* Fixed a compile error on NetBSD.
+
+* Fixed deadlock on Mac OS X.
+
+* Fixed a regression in `buffered_write_stream`.
+
+* Fixed a non-paged pool "leak" on Windows when an `io_service` is repeatedly
+ run without anything to do.
+
+* Reverted earlier change to allow some speculative operations to be performed
+ without holding the lock, as it introduced a race condition in some
+ multithreaded scenarios.
+
+* Fixed a bug where the second buffer in an array of two buffers may be ignored
+ if the first buffer is empty.
+
+[heading Asio 1.6.1]
+
+* Implemented various performance improvements, including:
+
+ * Using thread-local operation queues in single-threaded use cases (i.e. when
+ `concurrency_hint` is 1) to eliminate a lock/unlock pair.
+
+ * Allowing some `epoll_reactor` speculative operations to be performed
+ without holding the lock.
+
+ * Improving locality of reference by performing an `epoll_reactor`'s I/O
+ operation immediately before the corresponding handler is called. This also
+ improves scalability across CPUs when multiple threads are running the
+ `io_service`.
+
+ * Specialising asynchronous read and write operations for buffer sequences
+ that are arrays (`boost::array` or `std::array`) of exactly two buffers.
+
+* Fixed a compile error in the regex overload of `async_read_until`.
+
+* Fixed a Windows-specific compile error by explicitly specifying the
+ `signal()` function from the global namespace.
+
+* Changed the `deadline_timer` implementation so that it does not read the
+ clock unless the timer heap is non-empty.
+
+* Changed the SSL stream's buffers' sizes so that they are large enough to hold
+ a complete TLS record.
+
+* Fixed the behaviour of the synchronous `null_buffers` operations so that they
+ obey the user's non-blocking setting.
+
+* Changed to set the size of the select `fd_set` at runtime when using Windows.
+
+* Disabled an MSVC warning due to const qualifier being applied to function type.
+
+* Fixed a crash that occurs when using the Intel C++ compiler.
+
+* Changed the initialisation of the OpenSSL library so that it supports all
+ available algorithms.
+
+* Fixed the SSL error mapping used when the session is gracefully shut down.
+
+* Added some latency test programs.
+
+* Clarified that a read operation ends when the buffer is full.
+
+* Fixed an exception safety issue in `epoll_reactor` initialisation.
+
+* Made the number of strand implementations configurable by defining
+ `(BOOST_)ASIO_STRAND_IMPLEMENTATIONS` to the desired number.
+
+* Added support for a new `(BOOST_)ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION` flag
+ which switches the allocation of strand implementations to use a round-robin
+ approach rather than hashing.
+
+* Fixed potential strand starvation issue that can occur when `strand.post()`
+ is used.
+
+[heading Asio 1.6.0]
+
+* Improved support for C++0x move construction to further reduce copying of
+ handler objects. In certain designs it is possible to eliminate virtually all
+ copies. Move support is now enabled when compiling in [^-std=c++0x] mode on
+ g++ 4.5 or higher.
+
+* Added build support for platforms that don't provide either of `signal()` or
+ `sigaction()`.
+
+* Changed to use C++0x variadic templates when they are available, rather than
+ generating function overloads using the Boost.Preprocessor library.
+
+* Ensured the value of `errno` is preserved across the implementation's signal
+ handler.
+
+* On Windows, ensured the count of outstanding work is decremented for
+ abandoned operations (i.e. operations that are being cleaned up within the
+ `io_service` destructor).
+
+* Fixed behaviour of zero-length reads and writes in the new SSL implementation.
+
+* Added support for building with OpenSSL 1.0 when `OPENSSL_NO_SSL2` is defined.
+
+* Changed most examples to treat a failure by an accept operation as non-fatal.
+
+* Fixed an error in the [^tick_count_timer] example by making the duration type
+ signed. Previously, a wait on an already-passed deadline would not return for
+ a very long time.
+
+[heading Asio 1.5.3]
+
+* Added a new, completely rewritten SSL implementation. The new implementation
+ compiles faster, shows substantially improved performance, and supports
+ custom memory allocation and handler invocation. It includes new API features
+ such as certificate verification callbacks and has improved error reporting.
+ The new implementation is source-compatible with the old for most uses.
+ However, if necessary, the old implementation may still be used by defining
+ `(BOOST_)ASIO_ENABLE_OLD_SSL`.
+
+* Added new `asio::buffer()` overloads for `std::array`, when available. The
+ support is automatically enabled when compiling in [^-std=c++0x] mode on g++
+ 4.3 or higher, or when using MSVC 10. The support may be explicitly enabled
+ by defining `(BOOST_)ASIO_HAS_STD_ARRAY`, or disabled by defining
+ `(BOOST_)ASIO_DISABLE_STD_ARRAY`.
+
+* Changed to use the C++0x standard library templates `array`, `shared_ptr`,
+ `weak_ptr` and `atomic` when they are available, rather than the Boost
+ equivalents.
+
+* Support for `std::error_code` and `std::system_error` is no longer enabled by
+ default for g++ 4.5, as that compiler's standard library does not implement
+ `std::system_error::what()` correctly.
+
+[heading Asio 1.5.2]
+
+* Added support for C++0x move construction and assignment to sockets, serial
+ ports, POSIX descriptors and Windows handles.
+
+* Added support for the `fork()` system call. Programs that use `fork()` must
+ call `io_service.notify_fork()` at the appropriate times. Two new examples
+ have been added showing how to use this feature.
+
+* Cleaned up the handling of errors reported by the `close()` system call. In
+ particular, assume that most operating systems won't have `close()` fail with
+ `EWOULDBLOCK`, but if it does then set the blocking mode and restart the call.
+ If any other error occurs, assume the descriptor is closed.
+
+* The kqueue flag `EV_ONESHOT` seems to cause problems on some versions of Mac
+ OS X, with the `io_service` destructor getting stuck inside the `close()`
+ system call. Changed the kqueue backend to use `EV_CLEAR` instead.
+
+* Changed exception reporting to include the function name in exception `what()`
+ messages.
+
+* Fixed an insufficient initialisers warning with MinGW.
+
+* Changed the `shutdown_service()` member functions to be private.
+
+* Added archetypes for testing socket option functions.
+
+* Added a missing lock in `signal_set_service::cancel()`.
+
+* Fixed a copy/paste error in `SignalHandler` example.
+
+* Added the inclusion of the signal header to `signal_set_service.hpp` so that
+ constants like `NSIG` may be used.
+
+* Changed the `signal_set_service` implementation so that it doesn't assume
+ that `SIGRTMAX` is a compile-time constant.
+
+* Changed the Boost.Asio examples so that they don't use Boost.Thread's
+ convenience header. Use the header file that is specifically for the
+ boost::thread class instead.
+
+[heading Asio 1.5.1]
+
+* Added support for signal handling, using a new class called `signal_set`.
+ Programs may add one or more signals to the set, and then perform an
+ `async_wait()` operation. The specified handler will be called when one of
+ the signals occurs. The same signal number may registered with multiple
+ `signal_set` objects, however the signal number must be used only with Asio.
+
+* Added handler tracking, a new debugging aid. When enabled by defining
+ `(BOOST_)ASIO_ENABLE_HANDLER_TRACKING`, Asio writes debugging output to the
+ standard error stream. The output records asynchronous operations and the
+ relationships between their handlers. It may be post-processed using the
+ included [^handlerviz.pl] tool to create a visual representation of the
+ handlers (requires GraphViz).
+
+* Fixed a bug in `asio::streambuf` where the `consume()` function did not
+ always update the internal buffer pointers correctly. The problem may occur
+ when the `asio::streambuf` is filled with data using the standard C++ member
+ functions such as `sputn()`. (Note: the problem does not manifest when the
+ streambuf is populated by the Asio free functions `read()`,
+ `async_read()`, `read_until()` or `async_read_until()`.)
+
+* Fixed a bug on kqueue-based platforms, where reactor read operations that
+ return false from their `perform()` function are not correctly re-registered
+ with kqueue.
+
+* Support for `std::error_code` and `std::system_error` is no longer enabled by
+ default for MSVC10, as that compiler's standard library does not implement
+ `std::system_error::what()` correctly.
+
+* Modified the `buffers_iterator<>` and `ip::basic_resolver_iterator` classes
+ so that the value_type typedefs are non-const byte types.
+
+[heading Asio 1.5.0]
+
+* Added support for timeouts on socket iostreams, such as `ip::tcp::iostream`.
+ A timeout is set by calling `expires_at()` or `expires_from_now()` to
+ establish a deadline. Any socket operations which occur past the deadline
+ will put the iostream into a bad state.
+
+* Added a new `error()` member function to socket iostreams, for retrieving the
+ error code from the most recent system call.
+
+* Added a new `basic_deadline_timer::cancel_one()` function. This function lets
+ you cancel a single waiting handler on a timer. Handlers are cancelled in
+ FIFO order.
+
+* Added a new `transfer_exactly()` completion condition. This can be used to
+ send or receive a specified number of bytes even if the total size of the
+ buffer (or buffer sequence) is larger.
+
+* Added new free functions `connect()` and `async_connect()`. These operations
+ try each endpoint in a list until the socket is successfully connected.
+
+* Extended the `buffer_size()` function so that it works for buffer sequences
+ in addition to individual buffers.
+
+* Added a new `buffer_copy()` function that can be used to copy the raw bytes
+ between individual buffers and buffer sequences.
+
+* Added new non-throwing overloads of `read()`, `read_at()`, `write()` and
+ `write_at()` that do not require a completion condition.
+
+* Added friendlier compiler errors for when a completion handler does not meet
+ the necessary type requirements. When C++0x is available (currently supported
+ for g++ 4.5 or later, and MSVC 10), `static_assert` is also used to generate
+ an informative error message. This checking may be disabled by defining
+ `(BOOST_)ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS`.
+
+* Added support for using `std::error_code` and `std::system_error`, when
+ available. The support is automatically enabled when compiling in
+ [^-std=c++0x] mode on g++ 4.5 or higher, or when using MSVC 10. The support
+ may be explicitly enabled by defining `ASIO_HAS_STD_SYSTEM_ERROR`, or
+ disabled by defining `ASIO_DISABLE_STD_SYSTEM_ERROR`. (Available in non-Boost
+ version of Asio only.)
+
+* Made the `is_loopback()`, `is_unspecified()` and `is_multicast()` functions
+ consistently available across the `ip::address`, `ip::address_v4` and
+ `ip::address_v6` classes.
+
+* Added new `non_blocking()` functions for managing the non-blocking behaviour
+ of a socket or descriptor. The `io_control()` commands named `non_blocking_io`
+ are now deprecated in favour of these new functions.
+
+* Added new `native_non_blocking()` functions for managing the non-blocking
+ mode of the underlying socket or descriptor. These functions are intended to
+ allow the encapsulation of arbitrary non-blocking system calls as
+ asynchronous operations, in a way that is transparent to the user of the
+ socket object. The functions have no effect on the behaviour of the
+ synchronous operations of the socket or descriptor.
+
+* Added the `io_control()` member function for socket acceptors.
+
+* For consistency with the C++0x standard library, deprecated the `native_type`
+ typedefs in favour of `native_handle_type`, and the `native()` member
+ functions in favour of `native_handle()`.
+
+* Added a `release()` member function to posix descriptors. This function
+ releases ownership of the underlying native descriptor to the caller.
+
+* Added support for sequenced packet sockets (`SOCK_SEQPACKET`).
+
+* Added a new `io_service::stopped()` function that can be used to determine
+ whether the `io_service` has stopped (i.e. a `reset()` call is needed prior
+ to any further calls to `run()`, `run_one()`, `poll()` or `poll_one()`).
+
+* Reduced the copying of handler function objects.
+
+* Added support for C++0x move construction to further reduce copying of
+ handler objects. Move support is enabled when compiling in [^-std=c++0x] mode
+ on g++ 4.5 or higher, or when using MSVC10.
+
+* Removed the dependency on OS-provided macros for the well-known IPv4 and IPv6
+ addresses. This should eliminate the annoying "missing braces around
+ initializer" warnings.
+
+* Reduced the size of `ip::basic_endpoint<>` objects (such as
+ `ip::tcp::endpoint` and `ip::udp::endpoint`).
+
+* Changed the reactor backends to assume that any descriptors or sockets added
+ using `assign()` may have been `dup()`-ed, and so require explicit
+ deregistration from the reactor.
+
+* Changed the SSL error category to return error strings from the OpenSSL
+ library.
+
+* Changed the separate compilation support such that, to use Asio's SSL
+ capabilities, you should also include 'asio/ssl/impl/src.hpp` in one source
+ file in your program.
+
+* Removed the deprecated member functions named `io_service()`. The
+ `get_io_service()` member functions should be used instead.
+
+* Removed the deprecated typedefs `resolver_query` and `resolver_iterator` from
+ the `ip::tcp`, `ip::udp` and `ip::icmp` classes.
+
+* Fixed a compile error on some versions of g++ due to anonymous enums.
+
+* Added an explicit cast to the `FIONBIO` constant to int to suppress a compiler
+ warning on some platforms.
+
+* Fixed warnings reported by g++'s [^-Wshadow] compiler option.
+
+[heading Asio 1.4.8]
+
+* Fixed an integer overflow problem that occurs when
+ `ip::address_v4::broadcast()` is used on 64-bit platforms.
+
+* Fixed a problem on older Linux kernels (where epoll is used without `timerfd`
+ support) that prevents timely delivery of `deadline_timer` handlers, after the
+ program has been running for some time.
+
+[heading Asio 1.4.7]
+
+* Fixed a problem on kqueue-based platforms where a `deadline_timer` may
+ never fire if the `io_service` is running in a background thread.
+
+* Fixed a const-correctness issue that prevented valid uses of
+ `has_service<>` from compiling.
+
+* Fixed MinGW cross-compilation.
+
+* Removed dependency on deprecated Boost.System functions (Boost.Asio only).
+
+* Ensured `close()`/`closesocket()` failures are correctly propagated.
+
+* Added a check for errors returned by `InitializeCriticalSectionAndSpinCount`.
+
+* Added support for hardware flow control on QNX.
+
+* Always use `pselect()` on HP-UX, if it is available.
+
+* Ensured handler arguments are passed as lvalues.
+
+* Fixed Windows build when thread support is disabled.
+
+* Fixed a Windows-specific problem where `deadline_timer` objects with expiry
+ times set more than 5 minutes in the future may never expire.
+
+* Fixed the resolver backend on BSD platforms so that an empty service name
+ resolves to port number `0`, as per the documentation.
+
+* Fixed read operations so that they do not accept buffer sequences of type
+ `const_buffers_1`.
+
+* Redefined `Protocol` and `id` to avoid clashing with Objective-C++ keywords.
+
+* Fixed a `vector` reallocation performance issue that can occur when there are
+ many active `deadline_timer` objects.
+
+* Fixed the kqueue backend so that it compiles on NetBSD.
+
+* Fixed the socket `io_control()` implementation on 64-bit Mac OS X and BSD
+ platforms.
+
+* Fixed a Windows-specific problem where failures from `accept()` are
+ incorrectly treated as successes.
+
+* Deprecated the separate compilation header `asio/impl/src.cpp` in
+ favour of `asio/impl/src.hpp`.
+
+[heading Asio 1.4.6]
+
+* Reduced compile times. (Note that some programs may need to add additional
+ `#include`s, e.g. if the program uses boost::array but does not explicitly
+ include `<boost/array.hpp>`.)
+
+* Reduced the size of generated code.
+
+* Refactored `deadline_timer` implementation to improve performance.
+
+* Improved multiprocessor scalability on Windows by using a dedicated hidden
+ thread to wait for timers.
+
+* Improved performance of `asio::streambuf` with `async_read()` and
+ `async_read_until()`. These read operations now use the existing capacity of
+ the `streambuf` when reading, rather than limiting the read to 512 bytes.
+
+* Added optional separate compilation. To enable, include
+ `asio/impl/src.cpp` in one source file in a program, then
+ build the program with `(BOOST_)ASIO_SEPARATE_COMPILATION` defined in the
+ project\/compiler settings. Alternatively, `(BOOST_)ASIO_DYN_LINK` may be
+ defined to build a separately-compiled Asio as part of a shared library.
+
+* Added new macro `(BOOST_)ASIO_DISABLE_FENCED_BLOCK` to permit the disabling of
+ memory fences around completion handlers, even if thread support is enabled.
+
+* Reworked timeout examples to better illustrate typical use cases.
+
+* Ensured that handler arguments are passed as const types.
+
+* Fixed incorrect parameter order in `null_buffers` variant of `async_send_to`.
+
+* Ensured unsigned char is used with `isdigit` in `getaddrinfo` emulation.
+
+* Fixed handling of very small but non-zero timeouts.
+
+* Fixed crash that occurred when an empty buffer sequence was passed to a
+ composed read or write operation.
+
+* Added missing operator+ overload in `buffers_iterator`.
+
+* Implemented cancellation of `null_buffers` operations on Windows.
+
+[heading Asio 1.4.5]
+
+* Improved performance.
+
+* Reduced compile times.
+
+* Reduced the size of generated code.
+
+* Extended the guarantee that background threads don't call user code to
+ all asynchronous operations.
+
+* Changed to use edge-triggered epoll on Linux.
+
+* Changed to use `timerfd` for dispatching timers on Linux, when
+ available.
+
+* Changed to use one-shot notifications with kqueue on Mac OS X and BSD
+ platforms.
+
+* Added a bitmask type `ip::resolver_query_base::flags` as per the TR2
+ proposal. This type prevents implicit conversion from `int` to
+ `flags`, allowing the compiler to catch cases where users incorrectly
+ pass a numeric port number as the service name.
+
+* Added `#define NOMINMAX` for all Windows compilers. Users can define
+ `(BOOST_)ASIO_NO_NOMINMAX` to suppress this definition.
+
+* Fixed a bug where 0-byte asynchronous reads were incorrectly passing
+ an `error::eof` result to the completion handler.
+
+* Changed the `io_control()` member functions to always call `ioctl` on
+ the underlying descriptor when modifying blocking mode.
+
+* Changed the resolver implementation so that it no longer requires the
+ typedefs `InternetProtocol::resolver_query` and
+ `InternetProtocol::resolver_iterator`, as neither typedef is part of
+ the documented `InternetProtocol` requirements. The corresponding
+ typedefs in the `ip::tcp`, `ip::udp` and `ip::icmp` classes have been
+ deprecated.
+
+* Fixed out-of-band handling for reactors not based on `select()`.
+
+* Added new `(BOOST_)ASIO_DISABLE_THREADS` macro that allows Asio's
+ threading support to be independently disabled.
+
+* Minor documentation improvements.
+
+[heading Asio 1.4.4]
+
+* Added a new HTTP Server 4 example illustrating the use of stackless
+ coroutines with Asio.
+
+* Changed handler allocation and invocation to use `boost::addressof` to
+ get the address of handler objects, rather than applying `operator&`
+ directly.
+
+* Restricted MSVC buffer debugging workaround to 2008, as it causes a
+ crash with 2010 beta 2.
+
+* Fixed a problem with the lifetime of handler memory, where Windows
+ needs the `OVERLAPPED` structure to be valid until both the initiating
+ function call has returned and the completion packet has been
+ delivered.
+
+* Don't block signals while performing system calls, but instead restart
+ the calls if they are interrupted.
+
+* Documented the guarantee made by strand objects with respect to order
+ of handler invocation.
+
+* Changed strands to use a pool of implementations, to make copying of
+ strands cheaper.
+
+* Ensured that kqueue support is enabled for BSD platforms.
+
+* Added a `boost_` prefix to the `extern "C"` thread entry point
+ function.
+
+* In `getaddrinfo` emulation, only check the socket type (`SOCK_STREAM`
+ or `SOCK_DGRAM`) if a service name has been specified. This should
+ allow the emulation to work with raw sockets.
+
+* Added a workaround for some broken Windows firewalls that make a
+ socket appear bound to 0.0.0.0 when it is in fact bound to 127.0.0.1.
+
+* Applied a fix for reported excessive CPU usage under Solaris.
+
+* Added some support for platforms that use older compilers such as g++
+ 2.95.
+
+[heading Asio 1.4.3]
+
+* Added a new ping example to illustrate the use of ICMP sockets.
+
+* Changed the `buffered*_stream<>` templates to treat 0-byte reads and
+ writes as no-ops, to comply with the documented type requirements for
+ `SyncReadStream`, `AsyncReadStream`, `SyncWriteStream` and
+ `AsyncWriteStream`.
+
+* Changed some instances of the `throw` keyword to
+ `boost::throw_exception()` to allow Asio to be used when exception
+ support is disabled. Note that the SSL wrappers still require
+ exception support.
+
+* Made Asio compatible with the OpenSSL 1.0 beta.
+
+* Eliminated a redundant system call in the Solaris /dev/poll backend.
+
+* Fixed a bug in resizing of the bucket array in the internal hash maps.
+
+* Ensured correct propagation of the error code when a synchronous
+ accept fails.
+
+* Ensured correct propagation of the error code when a synchronous read
+ or write on a Windows `HANDLE` fails.
+
+* Fixed failures reported when `_GLIBCXX_DEBUG` is defined.
+
+* Fixed custom memory allocation support for timers.
+
+* Tidied up various warnings reported by g++.
+
+* Various documentation improvements, including more obvious hyperlinks
+ to function overloads, header file information, examples for the
+ handler type requirements, and adding enum values to the index.
+
+[heading Asio 1.4.2]
+
+* Implement automatic resizing of the bucket array in the internal hash
+ maps. This is to improve performance for very large numbers of
+ asynchronous operations and also to reduce memory usage for very small
+ numbers. A new macro `(BOOST_)ASIO_HASH_MAP_BUCKETS` may be used to
+ tweak the sizes used for the bucket arrays. (N.B. this feature
+ introduced a bug which was fixed in Asio 1.4.3 / Boost 1.40.)
+
+* Add performance optimisation for the Windows IOCP backend for when no
+ timers are used.
+
+* Prevent locale settings from affecting formatting of TCP and UDP
+ endpoints.
+
+* Fix a memory leak that occurred when an asynchronous SSL operation's
+ completion handler threw an exception.
+
+* Fix the implementation of `io_control()` so that it adheres to the
+ documented type requirements for IoControlCommand.
+
+* Fix incompatibility between Asio and ncurses.h.
+
+* On Windows, specifically handle the case when an overlapped `ReadFile`
+ call fails with `ERROR_MORE_DATA`. This enables a hack where a
+ `windows::stream_handle` can be used with a message-oriented named
+ pipe.
+
+* Fix system call wrappers to always clear the error on success, as
+ POSIX allows successful system calls to modify errno.
+
+* Don't include termios.h if `(BOOST_)ASIO_DISABLE_SERIAL_PORT` is
+ defined.
+
+* Cleaned up some more MSVC level 4 warnings.
+
+* Various documentation fixes.
+
+[heading Asio 1.4.1]
+
+* Improved compatibility with some Windows firewall software.
+
+* Ensured arguments to `windows::overlapped_ptr::complete()` are correctly
+ passed to the completion handler.
+
+* Fixed a link problem and multicast failure on QNX.
+
+* Fixed a compile error in SSL support on MinGW / g++ 3.4.5.
+
+* Drop back to using a pipe for notification if eventfd is not available
+ at runtime on Linux.
+
+* Various minor bug and documentation fixes.
+
+[heading Asio 1.4.0]
+
+* Enhanced CompletionCondition concept with the signature
+ `size_t CompletionCondition(error_code ec, size_t total)`, where the return
+ value indicates the maximum number of bytes to be transferred on the next
+ read or write operation. (The old CompletionCondition signature is still
+ supported for backwards compatibility).
+
+* New `windows::overlapped_ptr` class to allow arbitrary overlapped I/O
+ functions (such as `TransmitFile`) to be used with Asio.
+
+* On recent versions of Linux, an `eventfd` descriptor is now used (rather than
+ a pipe) to interrupt a blocked select/epoll reactor.
+
+* Added const overloads of `lowest_layer()`.
+
+* Synchronous read, write, accept and connect operations are now thread safe
+ (meaning that it is now permitted to perform concurrent synchronous
+ operations on an individual socket, if supported by the OS).
+
+* Reactor-based `io_service` implementations now use lazy initialisation to
+ reduce the memory usage of an `io_service` object used only as a message
+ queue.
+
+[heading Asio 1.2.0]
+
+* Added support for serial ports.
+
+* Added support for UNIX domain sockets.
+
+* Added support for raw sockets and ICMP.
+
+* Added wrappers for POSIX stream-oriented file descriptors (excluding regular
+ files).
+
+* Added wrappers for Windows stream-oriented `HANDLE`s such as named pipes
+ (requires `HANDLE`s that work with I/O completion ports).
+
+* Added wrappers for Windows random-access `HANDLE`s such as files (requires
+ `HANDLE`s that work with I/O completion ports).
+
+* Added support for reactor-style operations (i.e. they report readiness but
+ perform no I/O) using a new `null_buffers` type.
+
+* Added an iterator type for bytewise traversal of buffer sequences.
+
+* Added new `read_until()` and `async_read_until()` overloads that take a
+ user-defined function object for locating message boundaries.
+
+* Added an experimental two-lock queue (enabled by defining
+ `(BOOST_)ASIO_ENABLE_TWO_LOCK_QUEUE`) that may provide better `io_service`
+ scalability across many processors.
+
+* Various fixes, performance improvements, and more complete coverage of the
+ custom memory allocation support.
+
+[heading Asio 1.0.0]
+
+First stable release of Asio.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/index.xml b/3rdparty/asio/src/doc/index.xml
new file mode 100644
index 00000000000..3b7b556591c
--- /dev/null
+++ b/3rdparty/asio/src/doc/index.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../boost/tools/boostbook/dtd/boostbook.dtd">
+
+<!--
+ Copyright (c) 2003-2016 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)
+-->
+
+<section id="asio.index">
+ <index id="asio.index.index"/>
+</section>
diff --git a/3rdparty/asio/src/doc/makepdf.pl b/3rdparty/asio/src/doc/makepdf.pl
new file mode 100644
index 00000000000..4bb90a4d3de
--- /dev/null
+++ b/3rdparty/asio/src/doc/makepdf.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2003-2016 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)
+
+use strict;
+
+# Determine version number
+my $version = "X.Y.Z";
+open(VERSION, "../../include/asio/version.hpp") or die("Can't open version.hpp");
+while (my $line = <VERSION>)
+{
+ if ($line =~ /^#define ASIO_VERSION .* \/\/ (.*)$/)
+ {
+ $version = $1;
+ }
+}
+close(VERSION);
+
+# Generate PDF output
+system("bjam asioref");
+system("xsltproc --stringparam asio.version $version asioref.xsl asio.docbook > asioref.docbook");
+system("dblatex -I overview -s asioref.sty -P table.in.float=0 -o asioref-$version.pdf asioref.docbook");
+system("rm asioref.docbook");
diff --git a/3rdparty/asio/src/doc/noncopyable_dox.txt b/3rdparty/asio/src/doc/noncopyable_dox.txt
new file mode 100644
index 00000000000..949dabfc865
--- /dev/null
+++ b/3rdparty/asio/src/doc/noncopyable_dox.txt
@@ -0,0 +1,3 @@
+/**
+\class noncopyable
+*/
diff --git a/3rdparty/asio/src/doc/overview.qbk b/3rdparty/asio/src/doc/overview.qbk
new file mode 100644
index 00000000000..046b2cb6b6a
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview.qbk
@@ -0,0 +1,97 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:overview Overview]
+
+* [link asio.overview.rationale Rationale]
+* [link asio.overview.core Core Concepts and Functionality]
+ * [link asio.overview.core.basics Basic Asio Anatomy]
+ * [link asio.overview.core.async The Proactor Design Pattern: Concurrency Without Threads]
+ * [link asio.overview.core.threads Threads and Asio]
+ * [link asio.overview.core.strands Strands: Use Threads Without Explicit Locking]
+ * [link asio.overview.core.buffers Buffers]
+ * [link asio.overview.core.streams Streams, Short Reads and Short Writes]
+ * [link asio.overview.core.reactor Reactor-Style Operations]
+ * [link asio.overview.core.line_based Line-Based Operations]
+ * [link asio.overview.core.allocation Custom Memory Allocation]
+ * [link asio.overview.core.handler_tracking Handler Tracking]
+ * [link asio.overview.core.coroutine Stackless Coroutines]
+ * [link asio.overview.core.spawn Stackful Coroutines]
+* [link asio.overview.networking Networking]
+ * [link asio.overview.networking.protocols TCP, UDP and ICMP]
+ * [link asio.overview.networking.other_protocols Support for Other Protocols]
+ * [link asio.overview.networking.iostreams Socket Iostreams]
+ * [link asio.overview.networking.bsd_sockets The BSD Socket API and Asio]
+* [link asio.overview.timers Timers]
+* [link asio.overview.serial_ports Serial Ports]
+* [link asio.overview.signals Signal Handling]
+* [link asio.overview.posix POSIX-Specific Functionality]
+ * [link asio.overview.posix.local UNIX Domain Sockets]
+ * [link asio.overview.posix.stream_descriptor Stream-Oriented File Descriptors]
+* [link asio.overview.windows Windows-Specific Functionality]
+ * [link asio.overview.windows.stream_handle Stream-Oriented HANDLEs]
+ * [link asio.overview.windows.random_access_handle Random-Access HANDLEs]
+* [link asio.overview.ssl SSL]
+* [link asio.overview.cpp2011 C++ 2011 Support]
+* [link asio.overview.implementation Platform-Specific Implementation Notes]
+
+[include overview/rationale.qbk]
+
+[section:core Core Concepts and Functionality]
+
+* [link asio.overview.core.basics Basic Asio Anatomy]
+* [link asio.overview.core.async The Proactor Design Pattern: Concurrency Without Threads]
+* [link asio.overview.core.threads Threads and Asio]
+* [link asio.overview.core.strands Strands: Use Threads Without Explicit Locking]
+* [link asio.overview.core.buffers Buffers]
+* [link asio.overview.core.streams Streams, Short Reads and Short Writes]
+* [link asio.overview.core.reactor Reactor-Style Operations]
+* [link asio.overview.core.line_based Line-Based Operations]
+* [link asio.overview.core.allocation Custom Memory Allocation]
+* [link asio.overview.core.handler_tracking Handler Tracking]
+* [link asio.overview.core.coroutine Stackless Coroutines]
+* [link asio.overview.core.spawn Stackful Coroutines]
+
+[include overview/basics.qbk]
+[include overview/async.qbk]
+[include overview/threads.qbk]
+[include overview/strands.qbk]
+[include overview/buffers.qbk]
+[include overview/streams.qbk]
+[include overview/reactor.qbk]
+[include overview/line_based.qbk]
+[include overview/allocation.qbk]
+[include overview/handler_tracking.qbk]
+[include overview/coroutine.qbk]
+[include overview/spawn.qbk]
+
+[endsect]
+
+[section:networking Networking]
+
+* [link asio.overview.networking.protocols TCP, UDP and ICMP]
+* [link asio.overview.networking.other_protocols Support for Other Protocols]
+* [link asio.overview.networking.iostreams Socket Iostreams]
+* [link asio.overview.networking.bsd_sockets The BSD Socket API and Asio]
+
+[include overview/protocols.qbk]
+[include overview/other_protocols.qbk]
+[include overview/iostreams.qbk]
+[include overview/bsd_sockets.qbk]
+
+[endsect]
+
+[include overview/timers.qbk]
+[include overview/serial_ports.qbk]
+[include overview/signals.qbk]
+[include overview/posix.qbk]
+[include overview/windows.qbk]
+[include overview/ssl.qbk]
+[include overview/cpp2011.qbk]
+[include overview/implementation.qbk]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/allocation.qbk b/3rdparty/asio/src/doc/overview/allocation.qbk
new file mode 100644
index 00000000000..ecdc71a5011
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/allocation.qbk
@@ -0,0 +1,58 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:allocation Custom Memory Allocation]
+
+Many asynchronous operations need to allocate an object to store state
+associated with the operation. For example, a Win32 implementation needs
+`OVERLAPPED`-derived objects to pass to Win32 API functions.
+
+Furthermore, programs typically contain easily identifiable chains of
+asynchronous operations. A half duplex protocol implementation (e.g. an HTTP
+server) would have a single chain of operations per client (receives followed
+by sends). A full duplex protocol implementation would have two chains
+executing in parallel. Programs should be able to leverage this knowledge to
+reuse memory for all asynchronous operations in a chain.
+
+Given a copy of a user-defined `Handler` object `h`, if the implementation
+needs to allocate memory associated with that handler it will execute the code:
+
+ void* pointer = asio_handler_allocate(size, &h);
+
+Similarly, to deallocate the memory it will execute:
+
+ asio_handler_deallocate(pointer, size, &h);
+
+These functions are located using argument-dependent lookup. The implementation
+provides default implementations of the above functions in the `asio` namespace:
+
+ void* asio_handler_allocate(size_t, ...);
+ void asio_handler_deallocate(void*, size_t, ...);
+
+which are implemented in terms of `::operator new()` and `::operator delete()`
+respectively.
+
+The implementation guarantees that the deallocation will occur before the
+associated handler is invoked, which means the memory is ready to be reused for
+any new asynchronous operations started by the handler.
+
+The custom memory allocation functions may be called from any user-created
+thread that is calling a library function. The implementation guarantees that,
+for the asynchronous operations included the library, the implementation will
+not make concurrent calls to the memory allocation functions for that handler.
+The implementation will insert appropriate memory barriers to ensure correct
+memory visibility should allocation functions need to be called from different
+threads.
+
+[heading See Also]
+
+[link asio.reference.asio_handler_allocate asio_handler_allocate],
+[link asio.reference.asio_handler_deallocate asio_handler_deallocate],
+[link asio.examples.cpp03_examples.allocation custom memory allocation example (C++03)],
+[link asio.examples.cpp11_examples.allocation custom memory allocation example (C++11)].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/async.qbk b/3rdparty/asio/src/doc/overview/async.qbk
new file mode 100644
index 00000000000..ff627872416
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/async.qbk
@@ -0,0 +1,185 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:async The Proactor Design Pattern: Concurrency Without Threads]
+
+The Asio library offers side-by-side support for synchronous and asynchronous
+operations. The asynchronous support is based on the Proactor design pattern
+[link asio.overview.core.async.references \[POSA2\]]. The advantages and
+disadvantages of this approach, when compared to a synchronous-only or Reactor
+approach, are outlined below.
+
+[heading Proactor and Asio]
+
+Let us examine how the Proactor design pattern is implemented in Asio,
+without reference to platform-specific details.
+
+[$proactor.png]
+
+[*Proactor design pattern (adapted from \[POSA2\])]
+
+[mdash] Asynchronous Operation
+
+[:Defines an operation that is executed asynchronously, such as an asynchronous
+read or write on a socket.]
+
+[mdash] Asynchronous Operation Processor
+
+[:Executes asynchronous operations and queues events on a completion event
+queue when operations complete. From a high-level point of view, internal
+services like `reactive_socket_service` are asynchronous operation processors.]
+
+[mdash] Completion Event Queue
+
+[:Buffers completion events until they are dequeued by an asynchronous event
+demultiplexer.]
+
+[mdash] Completion Handler
+
+[:Processes the result of an asynchronous operation. These are function
+objects, often created using `boost::bind`.]
+
+[mdash] Asynchronous Event Demultiplexer
+
+[:Blocks waiting for events to occur on the completion event queue, and returns
+a completed event to its caller.]
+
+[mdash] Proactor
+
+[:Calls the asynchronous event demultiplexer to dequeue events, and dispatches
+the completion handler (i.e. invokes the function object) associated with the
+event. This abstraction is represented by the `io_context` class.]
+
+[mdash] Initiator
+
+[:Application-specific code that starts asynchronous operations. The initiator
+interacts with an asynchronous operation processor via a high-level interface
+such as `basic_stream_socket`, which in turn delegates to a service like
+`reactive_socket_service`.]
+
+[heading Implementation Using Reactor]
+
+On many platforms, Asio implements the Proactor design pattern in terms
+of a Reactor, such as `select`, `epoll` or `kqueue`. This implementation
+approach corresponds to the Proactor design pattern as follows:
+
+[mdash] Asynchronous Operation Processor
+
+[:A reactor implemented using `select`, `epoll` or `kqueue`. When the reactor
+indicates that the resource is ready to perform the operation, the processor
+executes the asynchronous operation and enqueues the associated completion
+handler on the completion event queue.]
+
+[mdash] Completion Event Queue
+
+[:A linked list of completion handlers (i.e. function objects).]
+
+[mdash] Asynchronous Event Demultiplexer
+
+[:This is implemented by waiting on an event or condition variable until a
+completion handler is available in the completion event queue.]
+
+[heading Implementation Using Windows Overlapped I/O]
+
+On Windows NT, 2000 and XP, Asio takes advantage of overlapped I/O to
+provide an efficient implementation of the Proactor design pattern. This
+implementation approach corresponds to the Proactor design pattern as follows:
+
+[mdash] Asynchronous Operation Processor
+
+[:This is implemented by the operating system. Operations are initiated by
+calling an overlapped function such as `AcceptEx`.]
+
+[mdash] Completion Event Queue
+
+[:This is implemented by the operating system, and is associated with an I/O
+completion port. There is one I/O completion port for each `io_context`
+instance.]
+
+[mdash] Asynchronous Event Demultiplexer
+
+[:Called by Asio to dequeue events and their associated completion
+handlers.]
+
+[heading Advantages]
+
+[mdash] Portability.
+
+[:Many operating systems offer a native asynchronous I/O API (such as
+overlapped I/O on __Windows__) as the preferred option for developing high
+performance network applications. The library may be implemented in terms of
+native asynchronous I/O. However, if native support is not available, the
+library may also be implemented using synchronous event demultiplexors that
+typify the Reactor pattern, such as __POSIX__ `select()`.]
+
+[mdash] Decoupling threading from concurrency.
+
+[:Long-duration operations are performed asynchronously by the implementation
+on behalf of the application. Consequently applications do not need to spawn
+many threads in order to increase concurrency.]
+
+[mdash] Performance and scalability.
+
+[:Implementation strategies such as thread-per-connection (which a
+synchronous-only approach would require) can degrade system performance, due to
+increased context switching, synchronisation and data movement among CPUs. With
+asynchronous operations it is possible to avoid the cost of context switching
+by minimising the number of operating system threads [mdash] typically a
+limited resource [mdash] and only activating the logical threads of control
+that have events to process.]
+
+[mdash] Simplified application synchronisation.
+
+[:Asynchronous operation completion handlers can be written as though they
+exist in a single-threaded environment, and so application logic can be
+developed with little or no concern for synchronisation issues.]
+
+[mdash] Function composition.
+
+[:Function composition refers to the implementation of functions to provide a
+higher-level operation, such as sending a message in a particular format. Each
+function is implemented in terms of multiple calls to lower-level read or write
+operations.]
+
+[:For example, consider a protocol where each message consists of a
+fixed-length header followed by a variable length body, where the length of the
+body is specified in the header. A hypothetical read_message operation could be
+implemented using two lower-level reads, the first to receive the header and,
+once the length is known, the second to receive the body.]
+
+[:To compose functions in an asynchronous model, asynchronous operations can be
+chained together. That is, a completion handler for one operation can initiate
+the next. Starting the first call in the chain can be encapsulated so that the
+caller need not be aware that the higher-level operation is implemented as a
+chain of asynchronous operations.]
+
+[:The ability to compose new operations in this way simplifies the development
+of higher levels of abstraction above a networking library, such as functions
+to support a specific protocol.]
+
+[heading Disadvantages]
+
+[mdash] Program complexity.
+
+[:It is more difficult to develop applications using asynchronous mechanisms
+due to the separation in time and space between operation initiation and
+completion. Applications may also be harder to debug due to the inverted flow
+of control.]
+
+[mdash] Memory usage.
+
+[:Buffer space must be committed for the duration of a read or write operation,
+which may continue indefinitely, and a separate buffer is required for each
+concurrent operation. The Reactor pattern, on the other hand, does not require
+buffer space until a socket is ready for reading or writing.]
+
+[heading References]
+
+\[POSA2\] D. Schmidt et al, ['Pattern Oriented Software Architecture, Volume
+2]. Wiley, 2000.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/async_op1.dot b/3rdparty/asio/src/doc/overview/async_op1.dot
new file mode 100644
index 00000000000..cbb95fb6949
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/async_op1.dot
@@ -0,0 +1,78 @@
+digraph g
+{
+ graph
+ [
+ nodesep="0.2"
+ ];
+
+ edge
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ labelfontname="Helvetica",
+ labelfontsize=10
+ ];
+
+ node
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ shape=box
+ ];
+
+ edge
+ [
+ arrowhead="open"
+ ]
+
+ // Program elements.
+ {
+ operating_system [ label="Operating System", shape=ellipse ];
+ io_context [ label="io_context" ];
+ io_object [ label="I/O Object\ne.g. socket" ];
+ your_program [ label="Your Program" ];
+ your_completion_handler [ label="Your Completion Handler" ];
+ }
+
+ // Owning relationships.
+ {
+ edge [ arrowtail="diamond" ];
+ your_program:e -> your_completion_handler:n;
+ your_program:w -> io_object:nw;
+ your_program:se -> io_context:ne;
+ }
+
+ // Non-owning relationships;
+ {
+ io_object:sw -> io_context:w;
+ }
+
+ // Visible actions.
+ {
+ edge [ style="dashed", color="#808080" ];
+
+ // Forward actions.
+ {
+ your_program:sw -> io_object:n [ label="1" ];
+ io_object:s -> io_context:nw [ label="2" ];
+ io_context:s -> operating_system:n [ label="3" ];
+ }
+ }
+
+ // Invisible actions.
+ {
+ edge [ style="invis" ];
+
+ // Forward actions.
+ {
+ your_program:s -> io_context:n [ label="5" ];
+ }
+
+ // Reverse actions.
+ {
+ edge [ arrowhead="none", arrowtail="open" ];
+ //io_context:s -> operating_system:n [ label="4" ];
+ your_completion_handler:s -> io_context:e [ label="6" ];
+ }
+ }
+}
diff --git a/3rdparty/asio/src/doc/overview/async_op1.png b/3rdparty/asio/src/doc/overview/async_op1.png
new file mode 100644
index 00000000000..464bc90e683
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/async_op1.png
Binary files differ
diff --git a/3rdparty/asio/src/doc/overview/async_op2.dot b/3rdparty/asio/src/doc/overview/async_op2.dot
new file mode 100644
index 00000000000..60a3275c391
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/async_op2.dot
@@ -0,0 +1,78 @@
+digraph g
+{
+ graph
+ [
+ nodesep="0.2"
+ ];
+
+ edge
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ labelfontname="Helvetica",
+ labelfontsize=10
+ ];
+
+ node
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ shape=box
+ ];
+
+ edge
+ [
+ arrowhead="open"
+ ]
+
+ // Program elements.
+ {
+ operating_system [ label="Operating System", shape=ellipse ];
+ io_context [ label="io_context" ];
+ io_object [ label="I/O Object\ne.g. socket" ];
+ your_program [ label="Your Program" ];
+ your_completion_handler [ label="Your Completion Handler" ];
+ }
+
+ // Owning relationships.
+ {
+ edge [ arrowtail="diamond" ];
+ your_program:e -> your_completion_handler:n;
+ your_program:w -> io_object:nw;
+ your_program:se -> io_context:ne;
+ }
+
+ // Non-owning relationships;
+ {
+ io_object:sw -> io_context:w;
+ }
+
+ // Visible actions.
+ {
+ edge [ style="dashed", color="#808080" ];
+
+ // Forward actions.
+ {
+ your_program:s -> io_context:n [ label="5" ];
+ }
+
+ // Reverse actions.
+ {
+ edge [ arrowhead="none", arrowtail="open" ];
+ io_context:s -> operating_system:n [ label="4" ];
+ your_completion_handler:s -> io_context:e [ label="6" ];
+ }
+ }
+
+ // Invisible actions.
+ {
+ edge [ style="invis" ];
+
+ // Forward actions.
+ {
+ your_program:sw -> io_object:n [ label="1" ];
+ io_object:s -> io_context:nw [ label="2" ];
+ //io_context:s -> operating_system:n [ label="3" ];
+ }
+ }
+}
diff --git a/3rdparty/asio/src/doc/overview/async_op2.png b/3rdparty/asio/src/doc/overview/async_op2.png
new file mode 100644
index 00000000000..ba256ec8e7f
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/async_op2.png
Binary files differ
diff --git a/3rdparty/asio/src/doc/overview/basics.qbk b/3rdparty/asio/src/doc/overview/basics.qbk
new file mode 100644
index 00000000000..c867563840a
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/basics.qbk
@@ -0,0 +1,106 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:basics Basic Asio Anatomy]
+
+Asio may be used to perform both synchronous and asynchronous operations on I/O
+objects such as sockets. Before using Asio it may be useful to get a conceptual
+picture of the various parts of Asio, your program, and how they work together.
+
+As an introductory example, let's consider what happens when you perform a
+connect operation on a socket. We shall start by examining synchronous
+operations.
+
+[$sync_op.png]
+
+[*Your program] will have at least one [*io_context] object. The [*io_context]
+represents [*your program]'s link to the [*operating system]'s I/O services.
+
+ asio::io_context io_context;
+
+To perform I/O operations [*your program] will need an [*I/O object] such as a
+TCP socket:
+
+ asio::ip::tcp::socket socket(io_context);
+
+When a synchronous connect operation is performed, the following sequence of
+events occurs:
+
+1. [*Your program] initiates the connect operation by calling the [*I/O
+object]:
+
+ socket.connect(server_endpoint);
+
+2. The [*I/O object] forwards the request to the [*io_context].
+
+3. The [*io_context] calls on the [*operating system] to perform the connect
+operation.
+
+4. The [*operating system] returns the result of the operation to the
+[*io_context].
+
+5. The [*io_context] translates any error resulting from the operation into an
+object of type `asio::error_code`. An `error_code` may be compared with
+specific values, or tested as a boolean (where a `false` result means that no
+error occurred). The result is then forwarded back up to the [*I/O object].
+
+6. The [*I/O object] throws an exception of type `asio::system_error` if the
+operation failed. If the code to initiate the operation had instead been
+written as:
+
+ asio::error_code ec;
+ socket.connect(server_endpoint, ec);
+
+then the `error_code` variable `ec` would be set to the result of the
+operation, and no exception would be thrown.
+
+When an asynchronous operation is used, a different sequence of events occurs.
+
+[$async_op1.png]
+
+1. [*Your program] initiates the connect operation by calling the [*I/O
+object]:
+
+ socket.async_connect(server_endpoint, your_completion_handler);
+
+where `your_completion_handler` is a function or function object with the
+signature:
+
+ void your_completion_handler(const asio::error_code& ec);
+
+The exact signature required depends on the asynchronous operation being
+performed. The reference documentation indicates the appropriate form for each
+operation.
+
+2. The [*I/O object] forwards the request to the [*io_context].
+
+3. The [*io_context] signals to the [*operating system] that it should start an
+asynchronous connect.
+
+Time passes. (In the synchronous case this wait would have been contained
+entirely within the duration of the connect operation.)
+
+[$async_op2.png]
+
+4. The [*operating system] indicates that the connect operation has completed
+by placing the result on a queue, ready to be picked up by the [*io_context].
+
+5. [*Your program] must make a call to `io_context::run()` (or to one of the
+similar [*io_context] member functions) in order for the result to be
+retrieved. A call to `io_context::run()` blocks while there are unfinished
+asynchronous operations, so you would typically call it as soon as you have
+started your first asynchronous operation.
+
+6. While inside the call to `io_context::run()`, the [*io_context] dequeues the
+result of the operation, translates it into an `error_code`, and then passes it
+to [*your completion handler].
+
+This is a simplified picture of how Asio operates. You will want to delve
+further into the documentation if your needs are more advanced, such as
+extending Asio to perform other types of asynchronous operations.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/bsd_sockets.qbk b/3rdparty/asio/src/doc/overview/bsd_sockets.qbk
new file mode 100644
index 00000000000..acc67da29d4
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/bsd_sockets.qbk
@@ -0,0 +1,270 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:bsd_sockets The BSD Socket API and Asio]
+
+The Asio library includes a low-level socket interface based on the BSD socket
+API, which is widely implemented and supported by extensive literature. It is
+also used as the basis for networking APIs in other languages, like Java. This
+low-level interface is designed to support the development of efficient and
+scalable applications. For example, it permits programmers to exert finer
+control over the number of system calls, avoid redundant data copying, minimise
+the use of resources like threads, and so on.
+
+Unsafe and error prone aspects of the BSD socket API not included. For example,
+the use of `int` to represent all sockets lacks type safety. The socket
+representation in Asio uses a distinct type for each protocol, e.g. for TCP one
+would use `ip::tcp::socket`, and for UDP one uses `ip::udp::socket`.
+
+The following table shows the mapping between the BSD socket API and Asio:
+
+[table
+ [
+ [BSD Socket API Elements]
+ [Equivalents in Asio]
+ ]
+ [
+ [socket descriptor - `int` (POSIX) or `SOCKET` (Windows)]
+ [ For TCP: [link asio.reference.ip__tcp.socket ip::tcp::socket],
+ [link asio.reference.ip__tcp.acceptor ip::tcp::acceptor]
+
+ For UDP: [link asio.reference.ip__udp.socket ip::udp::socket]
+
+ [link asio.reference.basic_socket basic_socket],
+ [link asio.reference.basic_stream_socket basic_stream_socket],
+ [link asio.reference.basic_datagram_socket basic_datagram_socket],
+ [link asio.reference.basic_raw_socket basic_raw_socket] ]
+ ]
+ [
+ [`in_addr`,
+ `in6_addr`]
+ [ [link asio.reference.ip__address ip::address],
+ [link asio.reference.ip__address ip::address_v4],
+ [link asio.reference.ip__address ip::address_v6] ]
+ ]
+ [
+ [`sockaddr_in`,
+ `sockaddr_in6`]
+ [ For TCP: [link asio.reference.ip__tcp.endpoint ip::tcp::endpoint]
+
+ For UDP: [link asio.reference.ip__udp.endpoint ip::udp::endpoint]
+
+ [link asio.reference.ip__basic_endpoint ip::basic_endpoint] ]
+ ]
+ [
+ [`accept()`]
+ [ For TCP: [link asio.reference.basic_socket_acceptor.accept ip::tcp::acceptor::accept()]
+
+ [link asio.reference.basic_socket_acceptor.accept basic_socket_acceptor::accept()] ]
+ ]
+ [
+ [`bind()`]
+ [ For TCP: [link asio.reference.basic_socket.bind ip::tcp::acceptor::bind()],
+ [link asio.reference.basic_socket.bind ip::tcp::socket::bind()]
+
+ For UDP: [link asio.reference.basic_socket.bind ip::udp::socket::bind()]
+
+ [link asio.reference.basic_socket.bind basic_socket::bind()] ]
+ ]
+ [
+ [`close()`]
+ [ For TCP: [link asio.reference.basic_socket.close ip::tcp::acceptor::close()],
+ [link asio.reference.basic_socket.close ip::tcp::socket::close()]
+
+ For UDP: [link asio.reference.basic_socket.close ip::udp::socket::close()]
+
+ [link asio.reference.basic_socket.close basic_socket::close()] ]
+ ]
+ [
+ [`connect()`]
+ [ For TCP: [link asio.reference.basic_socket.connect ip::tcp::socket::connect()]
+
+ For UDP: [link asio.reference.basic_socket.connect ip::udp::socket::connect()]
+
+ [link asio.reference.basic_socket.connect basic_socket::connect()] ]
+ ]
+ [
+ [`getaddrinfo()`,
+ `gethostbyaddr()`,
+ `gethostbyname()`,
+ `getnameinfo()`,
+ `getservbyname()`,
+ `getservbyport()`]
+ [ For TCP: [link asio.reference.ip__basic_resolver.resolve ip::tcp::resolver::resolve()],
+ [link asio.reference.ip__basic_resolver.async_resolve ip::tcp::resolver::async_resolve()]
+
+ For UDP: [link asio.reference.ip__basic_resolver.resolve ip::udp::resolver::resolve()],
+ [link asio.reference.ip__basic_resolver.async_resolve ip::udp::resolver::async_resolve()]
+
+ [link asio.reference.ip__basic_resolver.resolve ip::basic_resolver::resolve()],
+ [link asio.reference.ip__basic_resolver.async_resolve ip::basic_resolver::async_resolve()] ]
+ ]
+ [
+ [`gethostname()`]
+ [ [link asio.reference.ip__host_name ip::host_name()] ]
+ ]
+ [
+ [`getpeername()`]
+ [ For TCP: [link asio.reference.basic_socket.remote_endpoint ip::tcp::socket::remote_endpoint()]
+
+ For UDP: [link asio.reference.basic_socket.remote_endpoint ip::udp::socket::remote_endpoint()]
+
+ [link asio.reference.basic_socket.remote_endpoint basic_socket::remote_endpoint()] ]
+ ]
+ [
+ [`getsockname()`]
+ [ For TCP: [link asio.reference.basic_socket.local_endpoint ip::tcp::acceptor::local_endpoint()],
+ [link asio.reference.basic_socket.local_endpoint ip::tcp::socket::local_endpoint()]
+
+ For UDP: [link asio.reference.basic_socket.local_endpoint ip::udp::socket::local_endpoint()]
+
+ [link asio.reference.basic_socket.local_endpoint basic_socket::local_endpoint()] ]
+ ]
+ [
+ [`getsockopt()`]
+ [ For TCP: [link asio.reference.basic_socket.get_option ip::tcp::acceptor::get_option()],
+ [link asio.reference.basic_socket.get_option ip::tcp::socket::get_option()]
+
+ For UDP: [link asio.reference.basic_socket.get_option ip::udp::socket::get_option()]
+
+ [link asio.reference.basic_socket.get_option basic_socket::get_option()] ]
+ ]
+ [
+ [`inet_addr()`,
+ `inet_aton()`,
+ `inet_pton()`]
+ [ [link asio.reference.ip__address.from_string ip::address::from_string()],
+ [link asio.reference.ip__address.from_string ip::address_v4::from_string()],
+ [link asio.reference.ip__address.from_string ip_address_v6::from_string()] ]
+ ]
+ [
+ [`inet_ntoa()`,
+ `inet_ntop()`]
+ [ [link asio.reference.ip__address.to_string ip::address::to_string()],
+ [link asio.reference.ip__address.to_string ip::address_v4::to_string()],
+ [link asio.reference.ip__address.to_string ip_address_v6::to_string()] ]
+ ]
+ [
+ [`ioctl()`]
+ [ For TCP: [link asio.reference.basic_socket.io_control ip::tcp::socket::io_control()]
+
+ For UDP: [link asio.reference.basic_socket.io_control ip::udp::socket::io_control()]
+
+ [link asio.reference.basic_socket.io_control basic_socket::io_control()] ]
+ ]
+ [
+ [`listen()`]
+ [ For TCP: [link asio.reference.basic_socket_acceptor.listen ip::tcp::acceptor::listen()]
+
+ [link asio.reference.basic_socket_acceptor.listen basic_socket_acceptor::listen()] ]
+ ]
+ [
+ [`poll()`,
+ `select()`,
+ `pselect()`]
+ [ [link asio.reference.io_context.run io_context::run()],
+ [link asio.reference.io_context.run_one io_context::run_one()],
+ [link asio.reference.io_context.poll io_context::poll()],
+ [link asio.reference.io_context.poll_one io_context::poll_one()]
+
+ Note: in conjunction with asynchronous operations. ]
+ ]
+ [
+ [`readv()`,
+ `recv()`,
+ `read()`]
+ [ For TCP: [link asio.reference.basic_stream_socket.read_some ip::tcp::socket::read_some()],
+ [link asio.reference.basic_stream_socket.async_read_some ip::tcp::socket::async_read_some()],
+ [link asio.reference.basic_stream_socket.receive ip::tcp::socket::receive()],
+ [link asio.reference.basic_stream_socket.async_receive ip::tcp::socket::async_receive()]
+
+ For UDP: [link asio.reference.basic_datagram_socket.receive ip::udp::socket::receive()],
+ [link asio.reference.basic_datagram_socket.async_receive ip::udp::socket::async_receive()]
+
+ [link asio.reference.basic_stream_socket.read_some basic_stream_socket::read_some()],
+ [link asio.reference.basic_stream_socket.async_read_some basic_stream_socket::async_read_some()],
+ [link asio.reference.basic_stream_socket.receive basic_stream_socket::receive()],
+ [link asio.reference.basic_stream_socket.async_receive basic_stream_socket::async_receive()],
+ [link asio.reference.basic_datagram_socket.receive basic_datagram_socket::receive()],
+ [link asio.reference.basic_datagram_socket.async_receive basic_datagram_socket::async_receive()] ]
+ ]
+ [
+ [`recvfrom()`]
+ [ For UDP: [link asio.reference.basic_datagram_socket.receive_from ip::udp::socket::receive_from()],
+ [link asio.reference.basic_datagram_socket.async_receive_from ip::udp::socket::async_receive_from()]
+
+ [link asio.reference.basic_datagram_socket.receive_from basic_datagram_socket::receive_from()],
+ [link asio.reference.basic_datagram_socket.async_receive_from basic_datagram_socket::async_receive_from()] ]
+ ]
+ [
+ [`send()`,
+ `write()`,
+ `writev()`]
+ [ For TCP: [link asio.reference.basic_stream_socket.write_some ip::tcp::socket::write_some()],
+ [link asio.reference.basic_stream_socket.async_write_some ip::tcp::socket::async_write_some()],
+ [link asio.reference.basic_stream_socket.send ip::tcp::socket::send()],
+ [link asio.reference.basic_stream_socket.async_send ip::tcp::socket::async_send()]
+
+ For UDP: [link asio.reference.basic_datagram_socket.send ip::udp::socket::send()],
+ [link asio.reference.basic_datagram_socket.async_send ip::udp::socket::async_send()]
+
+ [link asio.reference.basic_stream_socket.write_some basic_stream_socket::write_some()],
+ [link asio.reference.basic_stream_socket.async_write_some basic_stream_socket::async_write_some()],
+ [link asio.reference.basic_stream_socket.send basic_stream_socket::send()],
+ [link asio.reference.basic_stream_socket.async_send basic_stream_socket::async_send()],
+ [link asio.reference.basic_datagram_socket.send basic_datagram_socket::send()],
+ [link asio.reference.basic_datagram_socket.async_send basic_datagram_socket::async_send()] ]
+ ]
+ [
+ [`sendto()`]
+ [ For UDP: [link asio.reference.basic_datagram_socket.send_to ip::udp::socket::send_to()],
+ [link asio.reference.basic_datagram_socket.async_send_to ip::udp::socket::async_send_to()]
+
+ [link asio.reference.basic_datagram_socket.send_to basic_datagram_socket::send_to()],
+ [link asio.reference.basic_datagram_socket.async_send_to basic_datagram_socket::async_send_to()] ]
+ ]
+ [
+ [`setsockopt()`]
+ [ For TCP: [link asio.reference.basic_socket.set_option ip::tcp::acceptor::set_option()],
+ [link asio.reference.basic_socket.set_option ip::tcp::socket::set_option()]
+
+ For UDP: [link asio.reference.basic_socket.set_option ip::udp::socket::set_option()]
+
+ [link asio.reference.basic_socket.set_option basic_socket::set_option()] ]
+ ]
+ [
+ [`shutdown()`]
+ [ For TCP: [link asio.reference.basic_socket.shutdown ip::tcp::socket::shutdown()]
+
+ For UDP: [link asio.reference.basic_socket.shutdown ip::udp::socket::shutdown()]
+
+ [link asio.reference.basic_socket.shutdown basic_socket::shutdown()] ]
+ ]
+ [
+ [`sockatmark()`]
+ [ For TCP: [link asio.reference.basic_socket.at_mark ip::tcp::socket::at_mark()]
+
+ [link asio.reference.basic_socket.at_mark basic_socket::at_mark()] ]
+ ]
+ [
+ [`socket()`]
+ [ For TCP: [link asio.reference.basic_socket.open ip::tcp::acceptor::open()],
+ [link asio.reference.basic_socket.open ip::tcp::socket::open()]
+
+ For UDP: [link asio.reference.basic_socket.open ip::udp::socket::open()]
+
+ [link asio.reference.basic_socket.open basic_socket::open()] ]
+ ]
+ [
+ [`socketpair()`]
+ [ [link asio.reference.local__connect_pair local::connect_pair()]
+
+ Note: POSIX operating systems only. ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/buffers.qbk b/3rdparty/asio/src/doc/overview/buffers.qbk
new file mode 100644
index 00000000000..bd8760d458f
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/buffers.qbk
@@ -0,0 +1,163 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:buffers Buffers]
+
+Fundamentally, I/O involves the transfer of data to and from contiguous regions
+of memory, called buffers. These buffers can be simply expressed as a tuple
+consisting of a pointer and a size in bytes. However, to allow the development
+of efficient network applications, Asio includes support for scatter-gather
+operations. These operations involve one or more buffers:
+
+* A scatter-read receives data into multiple buffers.
+* A gather-write transmits multiple buffers.
+
+Therefore we require an abstraction to represent a collection of buffers. The
+approach used in Asio is to define a type (actually two types) to
+represent a single buffer. These can be stored in a container, which may be
+passed to the scatter-gather operations.
+
+In addition to specifying buffers as a pointer and size in bytes, Asio makes a
+distinction between modifiable memory (called mutable) and non-modifiable
+memory (where the latter is created from the storage for a const-qualified
+variable). These two types could therefore be defined as follows:
+
+ typedef std::pair<void*, std::size_t> mutable_buffer;
+ typedef std::pair<const void*, std::size_t> const_buffer;
+
+Here, a mutable_buffer would be convertible to a const_buffer, but conversion
+in the opposite direction is not valid.
+
+However, Asio does not use the above definitions as-is, but instead defines two
+classes: `mutable_buffer` and `const_buffer`. The goal of these is to provide
+an opaque representation of contiguous memory, where:
+
+* Types behave as std::pair would in conversions. That is, a `mutable_buffer` is
+ convertible to a `const_buffer`, but the opposite conversion is disallowed.
+
+* There is protection against buffer overruns. Given a buffer instance, a user
+ can only create another buffer representing the same range of memory or a
+ sub-range of it. To provide further safety, the library also includes
+ mechanisms for automatically determining the size of a buffer from an array,
+ `boost::array` or `std::vector` of POD elements, or from a `std::string`.
+
+* The underlying memory is explicitly accessed using the `data()` member
+ function. In general an application should never need to do this, but it is
+ required by the library implementation to pass the raw memory to the
+ underlying operating system functions.
+
+Finally, multiple buffers can be passed to scatter-gather operations (such as
+[link asio.reference.read read()] or [link asio.reference.write write()]) by
+putting the buffer objects into a container. The `MutableBufferSequence` and
+`ConstBufferSequence` concepts have been defined so that containers such as
+`std::vector`, `std::list`, `std::vector` or `boost::array` can be used.
+
+[heading Streambuf for Integration with Iostreams]
+
+The class `asio::basic_streambuf` is derived from `std::basic_streambuf` to
+associate the input sequence and output sequence with one or more objects of
+some character array type, whose elements store arbitrary values. These
+character array objects are internal to the streambuf object, but direct access
+to the array elements is provided to permit them to be used with I/O
+operations, such as the send or receive operations of a socket:
+
+* The input sequence of the streambuf is accessible via the [link
+ asio.reference.basic_streambuf.data data()] member function. The return type
+ of this function meets the `ConstBufferSequence` requirements.
+
+* The output sequence of the streambuf is accessible via the [link
+ asio.reference.basic_streambuf.data prepare()] member function. The return
+ type of this function meets the `MutableBufferSequence` requirements.
+
+* Data is transferred from the front of the output sequence to the back of the
+ input sequence by calling the [link asio.reference.basic_streambuf.commit
+ commit()] member function.
+
+* Data is removed from the front of the input sequence by calling the [link
+ asio.reference.basic_streambuf.consume consume()] member function.
+
+The streambuf constructor accepts a `size_t` argument specifying the maximum of
+the sum of the sizes of the input sequence and output sequence. Any operation
+that would, if successful, grow the internal data beyond this limit will throw
+a `std::length_error` exception.
+
+[heading Bytewise Traversal of Buffer Sequences]
+
+The `buffers_iterator<>` class template allows buffer sequences (i.e. types
+meeting `MutableBufferSequence` or `ConstBufferSequence` requirements) to be
+traversed as though they were a contiguous sequence of bytes. Helper functions
+called buffers_begin() and buffers_end() are also provided, where the
+buffers_iterator<> template parameter is automatically deduced.
+
+As an example, to read a single line from a socket and into a `std::string`,
+you may write:
+
+ asio::streambuf sb;
+ ...
+ std::size_t n = asio::read_until(sock, sb, '\n');
+ asio::streambuf::const_buffers_type bufs = sb.data();
+ std::string line(
+ asio::buffers_begin(bufs),
+ asio::buffers_begin(bufs) + n);
+
+[heading Buffer Debugging]
+
+Some standard library implementations, such as the one that ships with
+Microsoft Visual C++ 8.0 and later, provide a feature called iterator
+debugging. What this means is that the validity of iterators is checked at
+runtime. If a program tries to use an iterator that has been invalidated, an
+assertion will be triggered. For example:
+
+ std::vector<int> v(1)
+ std::vector<int>::iterator i = v.begin();
+ v.clear(); // invalidates iterators
+ *i = 0; // assertion!
+
+Asio takes advantage of this feature to add buffer debugging. Consider the
+following code:
+
+ void dont_do_this()
+ {
+ std::string msg = "Hello, world!";
+ asio::async_write(sock, asio::buffer(msg), my_handler);
+ }
+
+When you call an asynchronous read or write you need to ensure that the buffers
+for the operation are valid until the completion handler is called. In the
+above example, the buffer is the `std::string` variable `msg`. This variable is
+on the stack, and so it goes out of scope before the asynchronous operation
+completes. If you're lucky then the application will crash, but random failures
+are more likely.
+
+When buffer debugging is enabled, Asio stores an iterator into the string until
+the asynchronous operation completes, and then dereferences it to check its
+validity. In the above example you would observe an assertion failure just
+before Asio tries to call the completion handler.
+
+This feature is automatically made available for Microsoft Visual Studio 8.0 or
+later and for GCC when `_GLIBCXX_DEBUG` is defined. There is a performance cost
+to this checking, so buffer debugging is only enabled in debug builds. For
+other compilers it may be enabled by defining `ASIO_ENABLE_BUFFER_DEBUGGING`.
+It can also be explicitly disabled by defining `ASIO_DISABLE_BUFFER_DEBUGGING`.
+
+[heading See Also]
+
+[link asio.reference.buffer buffer],
+[link asio.reference.buffers_begin buffers_begin],
+[link asio.reference.buffers_end buffers_end],
+[link asio.reference.buffers_iterator buffers_iterator],
+[link asio.reference.const_buffer const_buffer],
+[link asio.reference.const_buffers_1 const_buffers_1],
+[link asio.reference.mutable_buffer mutable_buffer],
+[link asio.reference.mutable_buffers_1 mutable_buffers_1],
+[link asio.reference.streambuf streambuf],
+[link asio.reference.ConstBufferSequence ConstBufferSequence],
+[link asio.reference.MutableBufferSequence MutableBufferSequence],
+[link asio.examples.cpp03_examples.buffers buffers example (C++03)],
+[link asio.examples.cpp11_examples.buffers buffers example (c++11)].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/coroutine.qbk b/3rdparty/asio/src/doc/overview/coroutine.qbk
new file mode 100644
index 00000000000..67453674eae
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/coroutine.qbk
@@ -0,0 +1,51 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:coroutine Stackless Coroutines]
+
+The [link asio.reference.coroutine `coroutine`] class provides support for
+stackless coroutines. Stackless coroutines enable programs to implement
+asynchronous logic in a synchronous manner, with minimal overhead, as shown in
+the following example:
+
+ struct session : asio::coroutine
+ {
+ boost::shared_ptr<tcp::socket> socket_;
+ boost::shared_ptr<std::vector<char> > buffer_;
+
+ session(boost::shared_ptr<tcp::socket> socket)
+ : socket_(socket),
+ buffer_(new std::vector<char>(1024))
+ {
+ }
+
+ void operator()(asio::error_code ec = asio::error_code(), std::size_t n = 0)
+ {
+ if (!ec) reenter (this)
+ {
+ for (;;)
+ {
+ yield socket_->async_read_some(asio::buffer(*buffer_), *this);
+ yield asio::async_write(*socket_, asio::buffer(*buffer_, n), *this);
+ }
+ }
+ }
+ };
+
+The `coroutine` class is used in conjunction with the pseudo-keywords
+`reenter`, `yield` and `fork`. These are preprocessor macros, and are
+implemented in terms of a `switch` statement using a technique similar to
+Duff's Device. The [link asio.reference.coroutine `coroutine`] class's
+documentation provides a complete description of these pseudo-keywords.
+
+[heading See Also]
+
+[link asio.reference.coroutine coroutine],
+[link asio.examples.cpp03_examples.http_server_4 HTTP Server 4 example],
+[link asio.overview.core.spawn Stackful Coroutines].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/cpp2011.qbk b/3rdparty/asio/src/doc/overview/cpp2011.qbk
new file mode 100644
index 00000000000..fa9e6622b67
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/cpp2011.qbk
@@ -0,0 +1,275 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:cpp2011 C++ 2011 Support]
+
+[/boostify: non-boost docs start here]
+
+[link asio.overview.cpp2011.system_error System Errors and Error Codes]
+
+[/boostify: non-boost docs end here]
+
+[link asio.overview.cpp2011.move_objects Movable I/O Objects]
+
+[link asio.overview.cpp2011.move_handlers Movable Handlers]
+
+[link asio.overview.cpp2011.variadic Variadic Templates]
+
+[link asio.overview.cpp2011.array Array Container]
+
+[link asio.overview.cpp2011.atomic Atomics]
+
+[link asio.overview.cpp2011.shared_ptr Shared Pointers]
+
+[link asio.overview.cpp2011.chrono Chrono]
+
+[link asio.overview.cpp2011.futures Futures]
+
+[/boostify: non-boost docs start here]
+
+[section:system_error System Errors and Error Codes]
+
+When available, Asio can use the `std::error_code` and `std::system_error`
+classes for reporting errors. In this case, the names `asio::error_code` and
+`asio::system_error` will be typedefs for these standard classes.
+
+System error support is automatically enabled for [^g++] 4.6 and later, when
+the [^-std=c++0x] or [^-std=gnu++0x] compiler options are used. It may be
+disabled by defining `ASIO_DISABLE_STD_SYSTEM_ERROR`, or explicitly enabled for
+other compilers by defining `ASIO_HAS_STD_SYSTEM_ERROR`.
+
+[endsect]
+
+[/boostify: non-boost docs end here]
+
+[section:move_objects Movable I/O Objects]
+
+When move support is available (via rvalue references), Asio allows move
+construction and assignment of sockets, serial ports, POSIX descriptors and
+Windows handles.
+
+Move support allows you to write code like:
+
+ tcp::socket make_socket(io_context& i)
+ {
+ tcp::socket s(i);
+ ...
+ std::move(s);
+ }
+
+or:
+
+ class connection : public enable_shared_from_this<connection>
+ {
+ private:
+ tcp::socket socket_;
+ ...
+ public:
+ connection(tcp::socket&& s) : socket_(std::move(s)) {}
+ ...
+ };
+
+ ...
+
+ class server
+ {
+ private:
+ tcp::acceptor acceptor_;
+ tcp::socket socket_;
+ ...
+ void handle_accept(error_code ec)
+ {
+ if (!ec)
+ std::make_shared<connection>(std::move(socket_))->go();
+ acceptor_.async_accept(socket_, ...);
+ }
+ ...
+ };
+
+as well as:
+
+ std::vector<tcp::socket> sockets;
+ sockets.push_back(tcp::socket(...));
+
+A word of warning: There is nothing stopping you from moving these objects
+while there are pending asynchronous operations, but it is unlikely to be a
+good idea to do so. In particular, composed operations like [link
+asio.reference.async_read async_read()] store a reference to the stream object.
+Moving during the composed operation means that the composed operation may
+attempt to access a moved-from object.
+
+Move support is automatically enabled for [^g++] 4.5 and later, when the
+[^-std=c++0x] or [^-std=gnu++0x] compiler options are used. It may be disabled
+by defining `ASIO_DISABLE_MOVE`, or explicitly enabled for other compilers by
+defining `ASIO_HAS_MOVE`. Note that these macros also affect the availability
+of [link asio.overview.cpp2011.move_handlers movable handlers].
+
+[endsect]
+
+[section:move_handlers Movable Handlers]
+
+As an optimisation, user-defined completion handlers may provide move
+constructors, and Asio's implementation will use a handler's move constructor
+in preference to its copy constructor. In certain circumstances, Asio may be
+able to eliminate all calls to a handler's copy constructor. However, handler
+types are still required to be copy constructible.
+
+When move support is enabled, asynchronous that are documented as follows:
+
+ template <typename Handler>
+ void async_XYZ(..., Handler handler);
+
+are actually declared as:
+
+ template <typename Handler>
+ void async_XYZ(..., Handler&& handler);
+
+The handler argument is perfectly forwarded and the move construction occurs
+within the body of `async_XYZ()`. This ensures that all other function
+arguments are evaluated prior to the move. This is critical when the other
+arguments to `async_XYZ()` are members of the handler. For example:
+
+ struct my_operation
+ {
+ shared_ptr<tcp::socket> socket;
+ shared_ptr<vector<char>> buffer;
+ ...
+ void operator(error_code ec, size_t length)
+ {
+ ...
+ socket->async_read_some(asio::buffer(*buffer), std::move(*this));
+ ...
+ }
+ };
+
+Move support is automatically enabled for [^g++] 4.5 and later, when the
+[^-std=c++0x] or [^-std=gnu++0x] compiler options are used. It may be disabled
+by defining `ASIO_DISABLE_MOVE`, or explicitly enabled for other compilers by
+defining `ASIO_HAS_MOVE`. Note that these macros also affect the availability
+of [link asio.overview.cpp2011.move_objects movable I/O objects].
+
+[endsect]
+
+[section:variadic Variadic Templates]
+
+When supported by a compiler, Asio can use variadic templates to implement the
+[link asio.reference.basic_socket_streambuf.connect
+basic_socket_streambuf::connect()] and [link
+asio.reference.basic_socket_iostream.connect basic_socket_iostream::connect()]
+functions.
+
+Support for variadic templates is automatically enabled for [^g++] 4.3 and
+later, when the [^-std=c++0x] or [^-std=gnu++0x] compiler options are used. It
+may be disabled by defining `ASIO_DISABLE_VARIADIC_TEMPLATES`, or explicitly
+enabled for other compilers by defining `ASIO_HAS_VARIADIC_TEMPLATES`.
+
+[endsect]
+
+[section:array Array Container]
+
+Where the standard library provides `std::array<>`, Asio:
+
+* Provides overloads for the [link asio.reference.buffer buffer()] function.
+
+* Uses it in preference to `boost::array<>` for the
+ [link asio.reference.ip__address_v4.bytes_type ip::address_v4::bytes_type] and
+ [link asio.reference.ip__address_v6.bytes_type ip::address_v6::bytes_type]
+ types.
+
+* Uses it in preference to `boost::array<>` where a fixed size array type is
+ needed in the implementation.
+
+Support for `std::array<>` is automatically enabled for [^g++] 4.3 and later,
+when the [^-std=c++0x] or [^-std=gnu++0x] compiler options are used, as well as
+for Microsoft Visual C++ 10. It may be disabled by defining
+`ASIO_DISABLE_STD_ARRAY`, or explicitly enabled for other compilers by
+defining `ASIO_HAS_STD_ARRAY`.
+
+[endsect]
+
+[section:atomic Atomics]
+
+Asio's implementation can use `std::atomic<>` in preference to
+`boost::detail::atomic_count`.
+
+Support for the standard atomic integer template is automatically enabled for
+[^g++] 4.5 and later, when the [^-std=c++0x] or [^-std=gnu++0x] compiler
+options are used. It may be disabled by defining `ASIO_DISABLE_STD_ATOMIC`, or
+explicitly enabled for other compilers by defining `ASIO_HAS_STD_ATOMIC`.
+
+[endsect]
+
+[section:shared_ptr Shared Pointers]
+
+Asio's implementation can use `std::shared_ptr<>` and `std::weak_ptr<>` in
+preference to the Boost equivalents.
+
+Support for the standard smart pointers is automatically enabled for [^g++] 4.3
+and later, when the [^-std=c++0x] or [^-std=gnu++0x] compiler options are used,
+as well as for Microsoft Visual C++ 10. It may be disabled by defining
+`ASIO_DISABLE_STD_SHARED_PTR`, or explicitly enabled for other compilers by
+defining `ASIO_HAS_STD_SHARED_PTR`.
+
+[endsect]
+
+[section:chrono Chrono]
+
+Asio provides timers based on the `std::chrono` facilities via the [link
+asio.reference.basic_waitable_timer basic_waitable_timer] class template.
+The typedefs [link asio.reference.system_timer system_timer], [link
+asio.reference.steady_timer steady_timer] and [link
+asio.reference.high_resolution_timer high_resolution_timer] utilise the
+standard clocks `system_clock`, `steady_clock` and `high_resolution_clock`
+respectively.
+
+Support for the `std::chrono` facilities is automatically enabled for [^g++]
+4.6 and later, when the [^-std=c++0x] or [^-std=gnu++0x] compiler options are
+used. (Note that, for [^g++], the draft-standard `monotonic_clock` is used in
+place of `steady_clock`.) Support may be disabled by defining
+`ASIO_DISABLE_STD_CHRONO`, or explicitly enabled for other compilers by
+defining `ASIO_HAS_STD_CHRONO`.
+
+When standard `chrono` is unavailable, Asio will otherwise use the Boost.Chrono
+library. The [link asio.reference.basic_waitable_timer basic_waitable_timer]
+class template may be used with either.
+
+[endsect]
+
+[section:futures Futures]
+
+The `asio::use_future` special value provides first-class support for returning a
+C++11 `std::future` from an asynchronous operation's initiating function.
+
+To use `asio::use_future`, pass it to an asynchronous operation instead of
+a normal completion handler. For example:
+
+ std::future<std::size_t> length =
+ my_socket.async_read_some(my_buffer, asio::use_future);
+
+Where a handler signature has the form:
+
+ void handler(asio::error_code ec, result_type result);
+
+the initiating function returns a `std::future` templated on `result_type`.
+In the above example, this is `std::size_t`. If the asynchronous operation
+fails, the `error_code` is converted into a `system_error` exception and
+passed back to the caller through the future.
+
+Where a handler signature has the form:
+
+ void handler(asio::error_code ec);
+
+the initiating function returns `std::future<void>`. As above, an error
+is passed back in the future as a `system_error` exception.
+
+[link asio.reference.use_future use_future],
+[link asio.reference.use_future_t use_future_t],
+[link asio.examples.cpp11_examples.futures Futures example (C++11)].
+
+[endsect]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/handler_tracking.qbk b/3rdparty/asio/src/doc/overview/handler_tracking.qbk
new file mode 100644
index 00000000000..3c2635254b5
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/handler_tracking.qbk
@@ -0,0 +1,102 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:handler_tracking Handler Tracking]
+
+To aid in debugging asynchronous programs, Asio provides support for handler
+tracking. When enabled by defining `ASIO_ENABLE_HANDLER_TRACKING`, Asio
+writes debugging output to the standard error stream. The output records
+asynchronous operations and the relationships between their handlers.
+
+[teletype]
+This feature is useful when debugging and you need to know how your
+asynchronous operations are chained together, or what the pending asynchronous
+operations are. As an illustration, here is the output when you run the HTTP
+Server example, handle a single request, then shut down via Ctrl+C:
+
+ @asio|1298160085.070638|0*1|signal_set@0x7fff50528f40.async_wait
+ @asio|1298160085.070888|0*2|socket@0x7fff50528f60.async_accept
+ @asio|1298160085.070913|0|resolver@0x7fff50528e28.cancel
+ @asio|1298160118.075438|>2|ec=asio.system:0
+ @asio|1298160118.075472|2*3|socket@0xb39048.async_receive
+ @asio|1298160118.075507|2*4|socket@0x7fff50528f60.async_accept
+ @asio|1298160118.075527|<2|
+ @asio|1298160118.075540|>3|ec=asio.system:0,bytes_transferred=122
+ @asio|1298160118.075731|3*5|socket@0xb39048.async_send
+ @asio|1298160118.075778|<3|
+ @asio|1298160118.075793|>5|ec=asio.system:0,bytes_transferred=156
+ @asio|1298160118.075831|5|socket@0xb39048.close
+ @asio|1298160118.075855|<5|
+ @asio|1298160122.827317|>1|ec=asio.system:0,signal_number=2
+ @asio|1298160122.827333|1|socket@0x7fff50528f60.close
+ @asio|1298160122.827359|<1|
+ @asio|1298160122.827370|>4|ec=asio.system:125
+ @asio|1298160122.827378|<4|
+ @asio|1298160122.827394|0|signal_set@0x7fff50528f40.cancel
+
+Each line is of the form:
+
+ <tag>|<timestamp>|<action>|<description>
+
+The `<tag>` is always `@asio`, and is used to identify and extract the handler
+tracking messages from the program output.
+
+The `<timestamp>` is seconds and microseconds from 1 Jan 1970 UTC.
+
+The `<action>` takes one of the following forms:
+
+[variablelist
+ [
+ [>n]
+ [The program entered the handler number `n`. The `<description>` shows the
+ arguments to the handler.]
+ ]
+ [
+ [<n]
+ [The program left handler number `n`.]
+ ]
+ [
+ [!n]
+ [The program left handler number n due to an exception.]
+ ]
+ [
+ [~n]
+ [The handler number `n` was destroyed without having been invoked. This is
+ usually the case for any unfinished asynchronous operations when the
+ `io_context` is destroyed.]
+ ]
+ [
+ [n*m]
+ [The handler number `n` created a new asynchronous operation with completion
+ handler number `m`. The `<description>` shows what asynchronous operation
+ was started.]
+ ]
+ [
+ [n]
+ [The handler number n performed some other operation. The `<description>`
+ shows what function was called. Currently only `close()` and `cancel()`
+ operations are logged, as these may affect the state of pending
+ asynchronous operations.]
+ ]
+]
+
+Where the `<description>` shows a synchronous or asynchronous operation, the
+format is `<object-type>@<pointer>.<operation>`. For handler entry, it shows a
+comma-separated list of arguments and their values.
+
+As shown above, Each handler is assigned a numeric identifier. Where the
+handler tracking output shows a handler number of 0, it means that the action
+was performed outside of any handler.
+
+[heading Visual Representations]
+
+The handler tracking output may be post-processed using the included
+[^handlerviz.pl] tool to create a visual representation of the handlers
+(requires the GraphViz tool [^dot]).
+[c++]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/implementation.qbk b/3rdparty/asio/src/doc/overview/implementation.qbk
new file mode 100644
index 00000000000..34c92f013e8
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/implementation.qbk
@@ -0,0 +1,305 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:implementation Platform-Specific Implementation Notes]
+
+This section lists platform-specific implementation details, such as the
+default demultiplexing mechanism, the number of threads created internally, and
+when threads are created.
+
+
+[heading Linux Kernel 2.4]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing. This means that the number of file
+descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+[heading Linux Kernel 2.6]
+
+Demultiplexing mechanism:
+
+* Uses `epoll` for demultiplexing.
+
+Threads:
+
+* Demultiplexing using `epoll` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading Solaris]
+
+Demultiplexing mechanism:
+
+* Uses [^/dev/poll] for demultiplexing.
+
+Threads:
+
+* Demultiplexing using [^/dev/poll] is performed in one of the threads that
+calls `io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading QNX Neutrino]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing. This means that the number of file
+descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading Mac OS X]
+
+Demultiplexing mechanism:
+
+* Uses `kqueue` for demultiplexing.
+
+Threads:
+
+* Demultiplexing using `kqueue` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading FreeBSD]
+
+Demultiplexing mechanism:
+
+* Uses `kqueue` for demultiplexing.
+
+Threads:
+
+* Demultiplexing using `kqueue` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading AIX]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing. This means that the number of file
+descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading HP-UX]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing. This means that the number of file
+descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading Tru64]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing. This means that the number of file
+descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.
+
+
+[heading Windows 95, 98 and Me]
+
+Demultiplexing mechanism:
+
+* Uses `select` for demultiplexing.
+
+Threads:
+
+* Demultiplexing using `select` is performed in one of the threads that calls
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* For sockets, at most 16 buffers may be transferred in a single operation.
+
+
+[heading Windows NT, 2000, XP, 2003, Vista, 7 and 8]
+
+Demultiplexing mechanism:
+
+* Uses overlapped I/O and I/O completion ports for all asynchronous socket
+operations except for asynchronous connect.
+
+* Uses `select` for emulating asynchronous connect.
+
+Threads:
+
+* Demultiplexing using I/O completion ports is performed in all threads that call
+`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
+`io_context::poll_one()`.
+
+* An additional thread per `io_context` is used to trigger timers. This thread
+is created on construction of the first `basic_deadline_timer` or
+`basic_waitable_timer` objects.
+
+* An additional thread per `io_context` is used for the `select`
+demultiplexing. This thread is created on the first call to `async_connect()`.
+
+* An additional thread per `io_context` is used to emulate asynchronous host
+resolution. This thread is created on the first call to either
+`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.
+
+Scatter-Gather:
+
+* For sockets, at most 64 buffers may be transferred in a single operation.
+
+* For stream-oriented handles, only one buffer may be transferred in a single
+operation.
+
+[heading Windows Runtime]
+
+Asio provides limited support for the Windows Runtime. It requires that the
+language extensions be enabled. Due to the restricted facilities exposed by the
+Windows Runtime API, the support comes with the following caveats:
+
+* The core facilities such as the `io_context`, `strand`, buffers, composed
+ operations, timers, etc., should all work as normal.
+
+* For sockets, only client-side TCP is supported.
+
+* Explicit binding of a client-side TCP socket is not supported.
+
+* The `cancel()` function is not supported for sockets. Asynchronous
+ operations may only be cancelled by closing the socket.
+
+* Operations that use `null_buffers` are not supported.
+
+* Only `tcp::no_delay` and `socket_base::keep_alive` options are supported.
+
+* Resolvers do not support service names, only numbers. I.e. you must
+ use "80" rather than "http".
+
+* Most resolver query flags have no effect.
+
+Demultiplexing mechanism:
+
+* Uses the `Windows::Networking::Sockets::StreamSocket` class to implement
+ asynchronous TCP socket operations.
+
+Threads:
+
+* Event completions are delivered to the Windows thread pool and posted to the
+ `io_context` for the handler to be executed.
+
+* An additional thread per `io_context` is used to trigger timers. This thread
+ is created on construction of the first timer objects.
+
+Scatter-Gather:
+
+* For sockets, at most one buffer may be transferred in a single operation.
+
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/iostreams.qbk b/3rdparty/asio/src/doc/overview/iostreams.qbk
new file mode 100644
index 00000000000..f738f9edec5
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/iostreams.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:iostreams Socket Iostreams]
+
+Asio includes classes that implement iostreams on top of sockets. These hide
+away the complexities associated with endpoint resolution, protocol
+independence, etc. To create a connection one might simply write:
+
+ ip::tcp::iostream stream("www.boost.org", "http");
+ if (!stream)
+ {
+ // Can't connect.
+ }
+
+The iostream class can also be used in conjunction with an acceptor to create
+simple servers. For example:
+
+ io_context ioc;
+
+ ip::tcp::endpoint endpoint(tcp::v4(), 80);
+ ip::tcp::acceptor acceptor(ios, endpoint);
+
+ for (;;)
+ {
+ ip::tcp::iostream stream;
+ acceptor.accept(stream.socket());
+ ...
+ }
+
+Timeouts may be set by calling `expires_at()` or `expires_from_now()` to
+establish a deadline. Any socket operations that occur past the deadline will
+put the iostream into a "bad" state.
+
+For example, a simple client program like this:
+
+ ip::tcp::iostream stream;
+ stream.expires_from_now(boost::posix_time::seconds(60));
+ stream.connect("www.boost.org", "http");
+ stream << "GET /LICENSE_1_0.txt HTTP/1.0\r\n";
+ stream << "Host: www.boost.org\r\n";
+ stream << "Accept: */*\r\n";
+ stream << "Connection: close\r\n\r\n";
+ stream.flush();
+ std::cout << stream.rdbuf();
+
+will fail if all the socket operations combined take longer than 60 seconds.
+
+If an error does occur, the iostream's `error()` member function may be used to
+retrieve the error code from the most recent system call:
+
+ if (!stream)
+ {
+ std::cout << "Error: " << stream.error().message() << "\n";
+ }
+
+[heading See Also]
+
+[link asio.reference.ip__tcp.iostream ip::tcp::iostream],
+[link asio.reference.basic_socket_iostream basic_socket_iostream],
+[link asio.examples.cpp03_examples.iostreams iostreams examples].
+
+[heading Notes]
+
+These iostream templates only support `char`, not `wchar_t`, and do not perform
+any code conversion.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/line_based.qbk b/3rdparty/asio/src/doc/overview/line_based.qbk
new file mode 100644
index 00000000000..df007adc3f8
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/line_based.qbk
@@ -0,0 +1,118 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:line_based Line-Based Operations]
+
+Many commonly-used internet protocols are line-based, which means that they
+have protocol elements that are delimited by the character sequence `"\r\n"`.
+Examples include HTTP, SMTP and FTP. To more easily permit the implementation
+of line-based protocols, as well as other protocols that use delimiters, Asio
+includes the functions `read_until()` and `async_read_until()`.
+
+The following example illustrates the use of `async_read_until()` in an HTTP
+server, to receive the first line of an HTTP request from a client:
+
+ class http_connection
+ {
+ ...
+
+ void start()
+ {
+ asio::async_read_until(socket_, data_, "\r\n",
+ boost::bind(&http_connection::handle_request_line, this, _1));
+ }
+
+ void handle_request_line(asio::error_code ec)
+ {
+ if (!ec)
+ {
+ std::string method, uri, version;
+ char sp1, sp2, cr, lf;
+ std::istream is(&data_);
+ is.unsetf(std::ios_base::skipws);
+ is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf;
+ ...
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket_;
+ asio::streambuf data_;
+ };
+
+The `streambuf` data member serves as a place to store the data that has been
+read from the socket before it is searched for the delimiter. It is important
+to remember that there may be additional data ['after] the delimiter. This
+surplus data should be left in the `streambuf` so that it may be inspected by a
+subsequent call to `read_until()` or `async_read_until()`.
+
+The delimiters may be specified as a single `char`, a `std::string` or a
+`boost::regex`. The `read_until()` and `async_read_until()` functions also
+include overloads that accept a user-defined function object called a match
+condition. For example, to read data into a streambuf until whitespace is
+encountered:
+
+ typedef asio::buffers_iterator<
+ asio::streambuf::const_buffers_type> iterator;
+
+ std::pair<iterator, bool>
+ match_whitespace(iterator begin, iterator end)
+ {
+ iterator i = begin;
+ while (i != end)
+ if (std::isspace(*i++))
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+ ...
+ asio::streambuf b;
+ asio::read_until(s, b, match_whitespace);
+
+To read data into a streambuf until a matching character is found:
+
+ class match_char
+ {
+ public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+ private:
+ char c_;
+ };
+
+ namespace asio {
+ template <> struct is_match_condition<match_char>
+ : public boost::true_type {};
+ } // namespace asio
+ ...
+ asio::streambuf b;
+ asio::read_until(s, b, match_char('a'));
+
+The `is_match_condition<>` type trait automatically evaluates to true for
+functions, and for function objects with a nested `result_type` typedef. For
+other types the trait must be explicitly specialised, as shown above.
+
+[heading See Also]
+
+[link asio.reference.async_read_until async_read_until()],
+[link asio.reference.is_match_condition is_match_condition],
+[link asio.reference.read_until read_until()],
+[link asio.reference.streambuf streambuf],
+[link asio.examples.cpp03_examples.http_client HTTP client example].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/other_protocols.qbk b/3rdparty/asio/src/doc/overview/other_protocols.qbk
new file mode 100644
index 00000000000..9a6fe077ea1
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/other_protocols.qbk
@@ -0,0 +1,94 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:other_protocols Support for Other Protocols]
+
+Support for other socket protocols (such as Bluetooth or IRCOMM sockets) can be
+added by implementing the [link asio.reference.Protocol protocol type
+requirements]. However, in many cases these protocols may also be used with
+Asio's generic protocol support. For this, Asio provides the following four
+classes:
+
+* [link asio.reference.generic__datagram_protocol `generic::datagram_protocol`]
+* [link asio.reference.generic__raw_protocol `generic::raw_protocol`]
+* [link asio.reference.generic__seq_packet_protocol `generic::seq_packet_protocol`]
+* [link asio.reference.generic__stream_protocol `generic::stream_protocol`]
+
+These classes implement the [link asio.reference.Protocol protocol type
+requirements], but allow the user to specify the address family (e.g. `AF_INET`)
+and protocol type (e.g. `IPPROTO_TCP`) at runtime. For example:
+
+ asio::generic::stream_protocol::socket my_socket(my_io_context);
+ my_socket.open(asio::generic::stream_protocol(AF_INET, IPPROTO_TCP));
+ ...
+
+An endpoint class template, [link asio.reference.generic__basic_endpoint
+`asio::generic::basic_endpoint`], is included to support these protocol
+classes. This endpoint can hold any other endpoint type, provided its native
+representation fits into a `sockaddr_storage` object. This class will also
+convert from other types that implement the [link asio.reference.Endpoint
+endpoint] type requirements:
+
+ asio::ip::tcp::endpoint my_endpoint1 = ...;
+ asio::generic::stream_protocol::endpoint my_endpoint2(my_endpoint1);
+
+The conversion is implicit, so as to support the following use cases:
+
+ asio::generic::stream_protocol::socket my_socket(my_io_context);
+ asio::ip::tcp::endpoint my_endpoint = ...;
+ my_socket.connect(my_endpoint);
+
+[heading C++11 Move Construction]
+
+When using C++11, it is possible to perform move construction from a socket (or
+acceptor) object to convert to the more generic protocol's socket (or acceptor)
+type. If the protocol conversion is valid:
+
+ Protocol1 p1 = ...;
+ Protocol2 p2(p1);
+
+then the corresponding socket conversion is allowed:
+
+ Protocol1::socket my_socket1(my_io_context);
+ ...
+ Protocol2::socket my_socket2(std::move(my_socket1));
+
+For example, one possible conversion is from a TCP socket to a generic
+stream-oriented socket:
+
+ asio::ip::tcp::socket my_socket1(my_io_context);
+ ...
+ asio::generic::stream_protocol::socket my_socket2(std::move(my_socket1));
+
+These conversions are also available for move-assignment.
+
+These conversions are not limited to the above generic protocol classes.
+User-defined protocols may take advantage of this feature by similarly ensuring
+the conversion from `Protocol1` to `Protocol2` is valid, as above.
+
+[heading Accepting Generic Sockets]
+
+As a convenience, a socket acceptor's `accept()` and `async_accept()` functions
+can directly accept into a different protocol's socket type, provided the
+corresponding protocol conversion is valid. For example, the following is
+supported because the protocol `asio::ip::tcp` is convertible to
+`asio::generic::stream_protocol`:
+
+ asio::ip::tcp::acceptor my_acceptor(my_io_context);
+ ...
+ asio::generic::stream_protocol::socket my_socket(my_io_context);
+ my_acceptor.accept(my_socket);
+
+[heading See Also]
+
+[link asio.reference.generic__datagram_protocol `generic::datagram_protocol`],
+[link asio.reference.generic__raw_protocol `generic::raw_protocol`],
+[link asio.reference.generic__seq_packet_protocol `generic::seq_packet_protocol`],
+[link asio.reference.generic__stream_protocol `generic::stream_protocol`],
+[link asio.reference.Protocol protocol type requirements].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/posix.qbk b/3rdparty/asio/src/doc/overview/posix.qbk
new file mode 100644
index 00000000000..19c91783e64
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/posix.qbk
@@ -0,0 +1,152 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:posix POSIX-Specific Functionality]
+
+[link asio.overview.posix.local UNIX Domain Sockets]
+
+[link asio.overview.posix.stream_descriptor Stream-Oriented File Descriptors]
+
+[link asio.overview.posix.fork Fork]
+
+[section:local UNIX Domain Sockets]
+
+Asio provides basic support UNIX domain sockets (also known as local sockets).
+The simplest use involves creating a pair of connected sockets. The following
+code:
+
+ local::stream_protocol::socket socket1(my_io_context);
+ local::stream_protocol::socket socket2(my_io_context);
+ local::connect_pair(socket1, socket2);
+
+will create a pair of stream-oriented sockets. To do the same for
+datagram-oriented sockets, use:
+
+ local::datagram_protocol::socket socket1(my_io_context);
+ local::datagram_protocol::socket socket2(my_io_context);
+ local::connect_pair(socket1, socket2);
+
+A UNIX domain socket server may be created by binding an acceptor to an
+endpoint, in much the same way as one does for a TCP server:
+
+ ::unlink("/tmp/foobar"); // Remove previous binding.
+ local::stream_protocol::endpoint ep("/tmp/foobar");
+ local::stream_protocol::acceptor acceptor(my_io_context, ep);
+ local::stream_protocol::socket socket(my_io_context);
+ acceptor.accept(socket);
+
+A client that connects to this server might look like:
+
+ local::stream_protocol::endpoint ep("/tmp/foobar");
+ local::stream_protocol::socket socket(my_io_context);
+ socket.connect(ep);
+
+Transmission of file descriptors or credentials across UNIX domain sockets is
+not directly supported within Asio, but may be achieved by accessing the
+socket's underlying descriptor using the [link
+asio.reference.basic_socket.native_handle native_handle()] member function.
+
+[heading See Also]
+
+[link asio.reference.local__connect_pair local::connect_pair],
+[link asio.reference.local__datagram_protocol local::datagram_protocol],
+[link asio.reference.local__datagram_protocol.endpoint local::datagram_protocol::endpoint],
+[link asio.reference.local__datagram_protocol.socket local::datagram_protocol::socket],
+[link asio.reference.local__stream_protocol local::stream_protocol],
+[link asio.reference.local__stream_protocol.acceptor local::stream_protocol::acceptor],
+[link asio.reference.local__stream_protocol.endpoint local::stream_protocol::endpoint],
+[link asio.reference.local__stream_protocol.iostream local::stream_protocol::iostream],
+[link asio.reference.local__stream_protocol.socket local::stream_protocol::socket],
+[link asio.examples.cpp03_examples.unix_domain_sockets UNIX domain sockets examples].
+
+[heading Notes]
+
+UNIX domain sockets are only available at compile time if supported by the
+target operating system. A program may test for the macro
+`ASIO_HAS_LOCAL_SOCKETS` to determine whether they are supported.
+
+[endsect]
+
+[section:stream_descriptor Stream-Oriented File Descriptors]
+
+Asio includes classes added to permit synchronous and asynchronous read and
+write operations to be performed on POSIX file descriptors, such as pipes,
+standard input and output, and various devices.
+
+These classes also provide limited support for regular files. This support
+assumes that the underlying read and write operations provided by the operating
+system never fail with `EAGAIN` or `EWOULDBLOCK`. (This assumption normally
+holds for buffered file I/O.) Synchronous and asynchronous read and write
+operations on file descriptors will succeed but the I/O will always be
+performed immediately. Wait operations, and operations involving
+`asio::null_buffers`, are not portably supported.
+
+For example, to perform read and write operations on standard input
+and output, the following objects may be created:
+
+ posix::stream_descriptor in(my_io_context, ::dup(STDIN_FILENO));
+ posix::stream_descriptor out(my_io_context, ::dup(STDOUT_FILENO));
+
+These are then used as synchronous or asynchronous read and write streams. This
+means the objects can be used with any of the [link asio.reference.read
+read()], [link asio.reference.async_read async_read()], [link
+asio.reference.write write()], [link asio.reference.async_write async_write()],
+[link asio.reference.read_until read_until()] or [link
+asio.reference.async_read_until async_read_until()] free functions.
+
+[heading See Also]
+
+[link asio.reference.posix__stream_descriptor posix::stream_descriptor],
+[link asio.examples.cpp03_examples.chat Chat example (C++03)],
+[link asio.examples.cpp11_examples.chat Chat example (C++11)].
+
+[heading Notes]
+
+POSIX stream descriptors are only available at compile time if supported by the
+target operating system. A program may test for the macro
+`ASIO_HAS_POSIX_STREAM_DESCRIPTOR` to determine whether they are supported.
+
+[endsect]
+
+[section:fork Fork]
+
+Asio supports programs that utilise the `fork()` system call. Provided the
+program calls `io_context.notify_fork()` at the appropriate times, Asio will
+recreate any internal file descriptors (such as the "self-pipe trick"
+descriptor used for waking up a reactor). The notification is usually performed
+as follows:
+
+ io_context_.notify_fork(asio::io_context::fork_prepare);
+ if (fork() == 0)
+ {
+ io_context_.notify_fork(asio::io_context::fork_child);
+ ...
+ }
+ else
+ {
+ io_context_.notify_fork(asio::io_context::fork_parent);
+ ...
+ }
+
+User-defined services can also be made fork-aware by overriding the
+`io_context::service::notify_fork()` virtual function.
+
+Note that any file descriptors accessible via Asio's public API (e.g. the
+descriptors underlying `basic_socket<>`, `posix::stream_descriptor`, etc.) are
+not altered during a fork. It is the program's responsibility to manage these
+as required.
+
+[heading See Also]
+
+[link asio.reference.io_context.notify_fork io_context::notify_fork()],
+[link asio.reference.io_context.fork_event io_context::fork_event],
+[link asio.reference.execution_context__service.notify_fork io_context::service::notify_fork()],
+[link asio.examples.cpp03_examples.fork Fork examples].
+
+[endsect]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/proactor.dot b/3rdparty/asio/src/doc/overview/proactor.dot
new file mode 100644
index 00000000000..871723408b9
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/proactor.dot
@@ -0,0 +1,100 @@
+digraph g
+{
+ edge
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ labelfontname="Helvetica",
+ labelfontsize=10
+ ];
+
+ node
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ shape=record
+ ];
+
+ initiator
+ [
+ label="Initiator"
+ ];
+
+ async_processor
+ [
+ label="Asynchronous\nOperation Processor"
+ ];
+
+ async_op
+ [
+ label="Asynchronous\nOperation"
+ ];
+
+ completion_queue
+ [
+ label="Completion\nEvent Queue"
+ ];
+
+ async_event_demuxer
+ [
+ label="Asynchronous\nEvent Demultiplexer"
+ ];
+
+ proactor
+ [
+ label="Proactor"
+ ];
+
+ handler
+ [
+ label="Completion\nHandler"
+ ];
+
+ initiator -> async_processor
+ [
+ label="uses",
+ style="dashed"
+ ];
+
+ initiator -> async_op
+ [
+ label="starts",
+ style="dashed"
+ ];
+
+ initiator -> handler
+ [
+ label="creates",
+ style="dashed"
+ ];
+
+ async_processor -> async_op
+ [
+ label="executes",
+ style="dashed"
+ ];
+
+ async_processor -> completion_queue
+ [
+ label="enqueues",
+ style="dashed"
+ ];
+
+ async_op -> handler;
+
+ async_event_demuxer -> completion_queue
+ [
+ label="dequeues",
+ style="dashed"
+ ];
+
+ proactor -> async_event_demuxer
+ [
+ ];
+
+ proactor -> handler
+ [
+ label="demultiplexes\n& dispatches"
+ style="dashed"
+ ];
+}
diff --git a/3rdparty/asio/src/doc/overview/proactor.png b/3rdparty/asio/src/doc/overview/proactor.png
new file mode 100644
index 00000000000..a0653b0106c
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/proactor.png
Binary files differ
diff --git a/3rdparty/asio/src/doc/overview/protocols.qbk b/3rdparty/asio/src/doc/overview/protocols.qbk
new file mode 100644
index 00000000000..eed070c7511
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/protocols.qbk
@@ -0,0 +1,149 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:protocols TCP, UDP and ICMP]
+
+Asio provides off-the-shelf support for the internet protocols TCP, UDP and
+ICMP.
+
+[heading TCP Clients]
+
+Hostname resolution is performed using a resolver, where host and service names
+are looked up and converted into one or more endpoints:
+
+ ip::tcp::resolver resolver(my_io_context);
+ ip::tcp::resolver::query query("www.boost.org", "http");
+ ip::tcp::resolver::iterator iter = resolver.resolve(query);
+ ip::tcp::resolver::iterator end; // End marker.
+ while (iter != end)
+ {
+ ip::tcp::endpoint endpoint = *iter++;
+ std::cout << endpoint << std::endl;
+ }
+
+The list of endpoints obtained above could contain both IPv4 and IPv6 endpoints,
+so a program should try each of them until it finds one that works. This keeps the
+client program independent of a specific IP version.
+
+To simplify the development of protocol-independent programs, TCP clients may
+establish connections using the free functions [link asio.reference.connect
+connect()] and [link asio.reference.async_connect async_connect()]. These
+operations try each endpoint in a list until the socket is successfully
+connected. For example, a single call:
+
+ ip::tcp::socket socket(my_io_context);
+ asio::connect(socket, resolver.resolve(query));
+
+will synchronously try all endpoints until one is successfully connected.
+Similarly, an asynchronous connect may be performed by writing:
+
+ asio::async_connect(socket_, iter,
+ boost::bind(&client::handle_connect, this,
+ asio::placeholders::error));
+
+ // ...
+
+ void handle_connect(const error_code& error)
+ {
+ if (!error)
+ {
+ // Start read or write operations.
+ }
+ else
+ {
+ // Handle error.
+ }
+ }
+
+When a specific endpoint is available, a socket can be created and connected:
+
+ ip::tcp::socket socket(my_io_context);
+ socket.connect(endpoint);
+
+Data may be read from or written to a connected TCP socket using the [link
+asio.reference.basic_stream_socket.receive receive()], [link
+asio.reference.basic_stream_socket.async_receive async_receive()], [link
+asio.reference.basic_stream_socket.send send()] or [link
+asio.reference.basic_stream_socket.async_send async_send()] member functions.
+However, as these could result in [link asio.overview.core.streams short writes
+or reads], an application will typically use the following operations instead:
+[link asio.reference.read read()], [link asio.reference.async_read
+async_read()], [link asio.reference.write write()] and [link
+asio.reference.async_write async_write()].
+
+[heading TCP Servers]
+
+A program uses an acceptor to accept incoming TCP connections:
+
+ ip::tcp::acceptor acceptor(my_io_context, my_endpoint);
+ ...
+ ip::tcp::socket socket(my_io_context);
+ acceptor.accept(socket);
+
+After a socket has been successfully accepted, it may be read from or written
+to as illustrated for TCP clients above.
+
+[heading UDP]
+
+UDP hostname resolution is also performed using a resolver:
+
+ ip::udp::resolver resolver(my_io_context);
+ ip::udp::resolver::query query("localhost", "daytime");
+ ip::udp::resolver::iterator iter = resolver.resolve(query);
+ ...
+
+A UDP socket is typically bound to a local endpoint. The following code will
+create an IP version 4 UDP socket and bind it to the "any" address on port
+`12345`:
+
+ ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
+ ip::udp::socket socket(my_io_context, endpoint);
+
+Data may be read from or written to an unconnected UDP socket using the [link
+asio.reference.basic_datagram_socket.receive_from receive_from()], [link
+asio.reference.basic_datagram_socket.async_receive_from async_receive_from()],
+[link asio.reference.basic_datagram_socket.send_to send_to()] or [link
+asio.reference.basic_datagram_socket.async_send_to async_send_to()] member
+functions. For a connected UDP socket, use the [link
+asio.reference.basic_datagram_socket.receive receive()], [link
+asio.reference.basic_datagram_socket.async_receive async_receive()], [link
+asio.reference.basic_datagram_socket.send send()] or [link
+asio.reference.basic_datagram_socket.async_send async_send()] member functions.
+
+[heading ICMP]
+
+As with TCP and UDP, ICMP hostname resolution is performed using a resolver:
+
+ ip::icmp::resolver resolver(my_io_context);
+ ip::icmp::resolver::query query("localhost", "");
+ ip::icmp::resolver::iterator iter = resolver.resolve(query);
+ ...
+
+An ICMP socket may be bound to a local endpoint. The following code will create
+an IP version 6 ICMP socket and bind it to the "any" address:
+
+ ip::icmp::endpoint endpoint(ip::icmp::v6(), 0);
+ ip::icmp::socket socket(my_io_context, endpoint);
+
+The port number is not used for ICMP.
+
+Data may be read from or written to an unconnected ICMP socket using the [link
+asio.reference.basic_raw_socket.receive_from receive_from()], [link
+asio.reference.basic_raw_socket.async_receive_from async_receive_from()],
+[link asio.reference.basic_raw_socket.send_to send_to()] or [link
+asio.reference.basic_raw_socket.async_send_to async_send_to()] member
+functions.
+
+[heading See Also]
+
+[link asio.reference.ip__tcp ip::tcp],
+[link asio.reference.ip__udp ip::udp],
+[link asio.reference.ip__icmp ip::icmp],
+[link asio.tutorial.tutdaytime1 daytime protocol tutorials],
+[link asio.examples.cpp03_examples.icmp ICMP ping example].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/rationale.qbk b/3rdparty/asio/src/doc/overview/rationale.qbk
new file mode 100644
index 00000000000..13491cd53d0
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/rationale.qbk
@@ -0,0 +1,54 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:rationale Rationale]
+
+Most programs interact with the outside world in some way, whether it be via a
+file, a network, a serial cable, or the console. Sometimes, as is the case with
+networking, individual I/O operations can take a long time to complete. This
+poses particular challenges to application development.
+
+Asio provides the tools to manage these long running operations, without
+requiring programs to use concurrency models based on threads and explicit
+locking.
+
+The Asio library is intended for programmers using C++ for systems programming,
+where access to operating system functionality such as networking is often
+required. In particular, Asio addresses the following goals:
+
+* [*Portability.] The library should support a range of commonly used operating
+systems, and provide consistent behaviour across these operating systems.
+
+* [*Scalability.] The library should facilitate the development of network
+applications that scale to thousands of concurrent connections. The library
+implementation for each operating system should use the mechanism that best
+enables this scalability.
+
+* [*Efficiency.] The library should support techniques such as scatter-gather
+I/O, and allow programs to minimise data copying.
+
+* [*Model concepts from established APIs, such as BSD sockets.] The
+BSD socket API is widely implemented and understood, and is covered in much
+literature. Other programming languages often use a similar interface for
+networking APIs. As far as is reasonable, Asio should leverage existing
+practice.
+
+* [*Ease of use.] The library should provide a lower entry barrier for new
+users by taking a toolkit, rather than framework, approach. That is, it should
+try to minimise the up-front investment in time to just learning a few basic
+rules and guidelines. After that, a library user should only need to understand
+the specific functions that are being used.
+
+* [*Basis for further abstraction.] The library should permit the development
+of other libraries that provide higher levels of abstraction. For example,
+implementations of commonly used protocols such as HTTP.
+
+Although Asio started life focused primarily on networking, its concepts of
+asynchronous I/O have been extended to include other operating system resources
+such as serial ports, file descriptors, and so on.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/reactor.qbk b/3rdparty/asio/src/doc/overview/reactor.qbk
new file mode 100644
index 00000000000..468645ad4c0
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/reactor.qbk
@@ -0,0 +1,44 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:reactor Reactor-Style Operations]
+
+Sometimes a program must be integrated with a third-party library that wants to
+perform the I/O operations itself. To facilitate this, Asio includes
+synchronous and asynchronous operations that may be used to wait for a socket
+to become ready to read, ready to write, or to have a pending error condition.
+
+As an example, to perform a non-blocking read something like the following may
+be used:
+
+ ip::tcp::socket socket(my_io_context);
+ ...
+ socket.non_blocking(true);
+ ...
+ socket.async_wait(ip::tcp::socket::wait_read, read_handler);
+ ...
+ void read_handler(asio::error_code ec)
+ {
+ if (!ec)
+ {
+ std::vector<char> buf(socket.available());
+ socket.read_some(buffer(buf));
+ }
+ }
+
+These operations are supported for sockets on all platforms, and for the POSIX
+stream-oriented descriptor classes.
+
+[heading See Also]
+
+[link asio.reference.basic_socket.wait basic_socket::wait()],
+[link asio.reference.basic_socket.async_wait basic_socket::async_wait()],
+[link asio.reference.basic_socket.non_blocking basic_socket::non_blocking()],
+[link asio.reference.basic_socket.native_non_blocking basic_socket::native_non_blocking()],
+[link asio.examples.cpp03_examples.nonblocking nonblocking example].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/serial_ports.qbk b/3rdparty/asio/src/doc/overview/serial_ports.qbk
new file mode 100644
index 00000000000..dd049cd2fa1
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/serial_ports.qbk
@@ -0,0 +1,45 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:serial_ports Serial Ports]
+
+Asio includes classes for creating and manipulating serial ports in a portable
+manner. For example, a serial port may be opened using:
+
+ serial_port port(my_io_context, name);
+
+where name is something like `"COM1"` on Windows, and `"/dev/ttyS0"` on POSIX
+platforms.
+
+Once opened, the serial port may be used as a [link asio.overview.core.streams
+stream]. This means the objects can be used with any of the [link
+asio.reference.read read()], [link asio.reference.async_read async_read()],
+[link asio.reference.write write()], [link asio.reference.async_write
+async_write()], [link asio.reference.read_until read_until()] or [link
+asio.reference.async_read_until async_read_until()] free functions.
+
+The serial port implementation also includes option classes for configuring the
+port's baud rate, flow control type, parity, stop bits and character size.
+
+[heading See Also]
+
+[link asio.reference.serial_port serial_port],
+[link asio.reference.serial_port_base serial_port_base],
+[link asio.reference.serial_port_base__baud_rate serial_port_base::baud_rate],
+[link asio.reference.serial_port_base__flow_control serial_port_base::flow_control],
+[link asio.reference.serial_port_base__parity serial_port_base::parity],
+[link asio.reference.serial_port_base__stop_bits serial_port_base::stop_bits],
+[link asio.reference.serial_port_base__character_size serial_port_base::character_size].
+
+[heading Notes]
+
+Serial ports are available on all POSIX platforms. For Windows, serial ports
+are only available at compile time when the I/O completion port backend is used
+(which is the default). A program may test for the macro
+`ASIO_HAS_SERIAL_PORT` to determine whether they are supported.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/signals.qbk b/3rdparty/asio/src/doc/overview/signals.qbk
new file mode 100644
index 00000000000..d626ead861c
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/signals.qbk
@@ -0,0 +1,44 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:signals Signal Handling]
+
+Asio supports signal handling using a class called [link
+asio.reference.signal_set signal_set]. Programs may add one or more signals to
+the set, and then perform an `async_wait()` operation. The specified handler
+will be called when one of the signals occurs. The same signal number may be
+registered with multiple [link asio.reference.signal_set signal_set] objects,
+however the signal number must be used only with Asio.
+
+ void handler(
+ const asio::error_code& error,
+ int signal_number)
+ {
+ if (!error)
+ {
+ // A signal occurred.
+ }
+ }
+
+ ...
+
+ // Construct a signal set registered for process termination.
+ asio::signal_set signals(io_context, SIGINT, SIGTERM);
+
+ // Start an asynchronous wait for one of the signals to occur.
+ signals.async_wait(handler);
+
+Signal handling also works on Windows, as the Microsoft Visual C++ runtime
+library maps console events like Ctrl+C to the equivalent signal.
+
+[heading See Also]
+
+[link asio.reference.signal_set signal_set],
+[link asio.examples.cpp03_examples.http_server HTTP server example (C++03)],
+[link asio.examples.cpp11_examples.http_server HTTP server example (C++11)].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/spawn.qbk b/3rdparty/asio/src/doc/overview/spawn.qbk
new file mode 100644
index 00000000000..908d78f72ae
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/spawn.qbk
@@ -0,0 +1,102 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:spawn Stackful Coroutines]
+
+The [link asio.reference.spawn `spawn()`] function is a high-level wrapper for
+running stackful coroutines. It is based on the Boost.Coroutine library. The
+`spawn()` function enables programs to implement asynchronous logic in a
+synchronous manner, as shown in the following example:
+
+ asio::spawn(my_strand, do_echo);
+
+ // ...
+
+ void do_echo(asio::yield_context yield)
+ {
+ try
+ {
+ char data[128];
+ for (;;)
+ {
+ std::size_t length =
+ my_socket.async_read_some(
+ asio::buffer(data), yield);
+
+ asio::async_write(my_socket,
+ asio::buffer(data, length), yield);
+ }
+ }
+ catch (std::exception& e)
+ {
+ // ...
+ }
+ }
+
+The first argument to `spawn()` may be a
+[link asio.reference.io_context__strand `strand`],
+[link asio.reference.io_context `io_context`], or
+[link asio.reference.CompletionHandler completion handler].
+This argument determines the context in which the coroutine is permitted to
+execute. For example, a server's per-client object may consist of multiple
+coroutines; they should all run on the same `strand` so that no explicit
+synchronisation is required.
+
+The second argument is a function object with signature:
+
+ void coroutine(asio::yield_context yield);
+
+that specifies the code to be run as part of the coroutine. The parameter
+`yield` may be passed to an asynchronous operation in place of the completion
+handler, as in:
+
+ std::size_t length =
+ my_socket.async_read_some(
+ asio::buffer(data), yield);
+
+This starts the asynchronous operation and suspends the coroutine. The
+coroutine will be resumed automatically when the asynchronous operation
+completes.
+
+Where an asynchronous operation's handler signature has the form:
+
+ void handler(asio::error_code ec, result_type result);
+
+the initiating function returns the result_type. In the `async_read_some`
+example above, this is `size_t`. If the asynchronous operation fails, the
+`error_code` is converted into a `system_error` exception and thrown.
+
+Where a handler signature has the form:
+
+ void handler(asio::error_code ec);
+
+the initiating function returns `void`. As above, an error is passed back to
+the coroutine as a `system_error` exception.
+
+To collect the `error_code` from an operation, rather than have it throw an
+exception, associate the output variable with the `yield_context` as follows:
+
+ asio::error_code ec;
+ std::size_t length =
+ my_socket.async_read_some(
+ asio::buffer(data), yield[ec]);
+
+[*Note:] if `spawn()` is used with a custom completion handler of type
+`Handler`, the function object signature is actually:
+
+ void coroutine(asio::basic_yield_context<Handler> yield);
+
+[heading See Also]
+
+[link asio.reference.spawn spawn],
+[link asio.reference.yield_context yield_context],
+[link asio.reference.basic_yield_context basic_yield_context],
+[link asio.examples.cpp03_examples.spawn Spawn example (C++03)],
+[link asio.examples.cpp11_examples.spawn Spawn example (C++11)],
+[link asio.overview.core.coroutine Stackless Coroutines].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/ssl.qbk b/3rdparty/asio/src/doc/overview/ssl.qbk
new file mode 100644
index 00000000000..e5a4d73c010
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/ssl.qbk
@@ -0,0 +1,123 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ssl SSL]
+
+Asio contains classes and class templates for basic SSL support. These classes
+allow encrypted communication to be layered on top of an existing stream, such
+as a TCP socket.
+
+Before creating an encrypted stream, an application must construct an SSL
+context object. This object is used to set SSL options such as verification
+mode, certificate files, and so on. As an illustration, client-side
+initialisation may look something like:
+
+ ssl::context ctx(ssl::context::sslv23);
+ ctx.set_verify_mode(ssl::verify_peer);
+ ctx.load_verify_file("ca.pem");
+
+To use SSL with a TCP socket, one may write:
+
+ ssl::stream<ip::tcp::socket> ssl_sock(my_io_context, ctx);
+
+To perform socket-specific operations, such as establishing an outbound
+connection or accepting an incoming one, the underlying socket must first be
+obtained using the `ssl::stream` template's [link
+asio.reference.ssl__stream.lowest_layer `lowest_layer()`] member function:
+
+ ip::tcp::socket::lowest_layer_type& sock = ssl_sock.lowest_layer();
+ sock.connect(my_endpoint);
+
+In some use cases the underlying stream object will need to have a longer
+lifetime than the SSL stream, in which case the template parameter should be a
+reference to the stream type:
+
+ ip::tcp::socket sock(my_io_context);
+ ssl::stream<ip::tcp::socket&> ssl_sock(sock, ctx);
+
+SSL handshaking must be performed prior to transmitting or receiving data over
+an encrypted connection. This is accomplished using the `ssl::stream`
+template's [link asio.reference.ssl__stream.handshake handshake()] or [link
+asio.reference.ssl__stream.async_handshake async_handshake()] member functions.
+
+Once connected, SSL stream objects are used as synchronous or asynchronous read
+and write streams. This means the objects can be used with any of the [link
+asio.reference.read read()], [link asio.reference.async_read async_read()],
+[link asio.reference.write write()], [link asio.reference.async_write
+async_write()], [link asio.reference.read_until read_until()] or [link
+asio.reference.async_read_until async_read_until()] free functions.
+
+[heading Certificate Verification]
+
+Asio provides various methods for configuring the way SSL certificates are
+verified:
+
+* [link asio.reference.ssl__context.set_default_verify_paths ssl::context::set_default_verify_paths()]
+* [link asio.reference.ssl__context.set_verify_mode ssl::context::set_verify_mode()]
+* [link asio.reference.ssl__context.set_verify_callback ssl::context::set_verify_callback()]
+* [link asio.reference.ssl__context.load_verify_file ssl::context::load_verify_file()]
+* [link asio.reference.ssl__stream.set_verify_mode ssl::stream::set_verify_mode()]
+* [link asio.reference.ssl__stream.set_verify_callback ssl::stream::set_verify_callback()]
+
+To simplify use cases where certificates are verified according to the rules in
+RFC 2818 (certificate verification for HTTPS), Asio provides a reusable
+verification callback as a function object:
+
+* [link asio.reference.ssl__rfc2818_verification ssl::rfc2818_verification]
+
+The following example shows verification of a remote host's certificate
+according to the rules used by HTTPS:
+
+ using asio::ip::tcp;
+ namespace ssl = asio::ssl;
+ typedef ssl::stream<tcp::socket> ssl_socket;
+
+ // Create a context that uses the default paths for
+ // finding CA certificates.
+ ssl::context ctx(ssl::context::sslv23);
+ ctx.set_default_verify_paths();
+
+ // Open a socket and connect it to the remote host.
+ asio::io_context io_context;
+ ssl_socket sock(io_context, ctx);
+ tcp::resolver resolver(io_context);
+ tcp::resolver::query query("host.name", "https");
+ asio::connect(sock.lowest_layer(), resolver.resolve(query));
+ sock.lowest_layer().set_option(tcp::no_delay(true));
+
+ // Perform SSL handshake and verify the remote host's
+ // certificate.
+ sock.set_verify_mode(ssl::verify_peer);
+ sock.set_verify_callback(ssl::rfc2818_verification("host.name"));
+ sock.handshake(ssl_socket::client);
+
+ // ... read and write as normal ...
+
+[heading SSL and Threads]
+
+SSL stream objects perform no locking of their own. Therefore, it is essential
+that all asynchronous SSL operations are performed in an implicit or explicit
+[link asio.overview.core.strands strand]. Note that this means that no
+synchronisation is required (and so no locking overhead is incurred) in single
+threaded programs.
+
+[heading See Also]
+
+[link asio.reference.ssl__context ssl::context],
+[link asio.reference.ssl__rfc2818_verification ssl::rfc2818_verification],
+[link asio.reference.ssl__stream ssl::stream],
+[link asio.examples.cpp03_examples.ssl SSL example].
+
+[heading Notes]
+
+[@http://www.openssl.org OpenSSL] is required to make use of Asio's SSL
+support. When an application needs to use OpenSSL functionality that is not
+wrapped by Asio, the underlying OpenSSL types may be obtained by calling [link
+asio.reference.ssl__context.native_handle `ssl::context::native_handle()`] or
+[link asio.reference.ssl__stream.native_handle `ssl::stream::native_handle()`].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/strands.qbk b/3rdparty/asio/src/doc/overview/strands.qbk
new file mode 100644
index 00000000000..0b6ff050dc6
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/strands.qbk
@@ -0,0 +1,85 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:strands Strands: Use Threads Without Explicit Locking]
+
+A strand is defined as a strictly sequential invocation of event handlers (i.e.
+no concurrent invocation). Use of strands allows execution of code in a
+multithreaded program without the need for explicit locking (e.g. using
+mutexes).
+
+Strands may be either implicit or explicit, as illustrated by the following
+alternative approaches:
+
+* Calling io_context::run() from only one thread means all event handlers
+ execute in an implicit strand, due to the io_context's guarantee that handlers
+ are only invoked from inside run().
+
+* Where there is a single chain of asynchronous operations associated with a
+ connection (e.g. in a half duplex protocol implementation like HTTP) there is
+ no possibility of concurrent execution of the handlers. This is an implicit
+ strand.
+
+* An explicit strand is an instance of `strand<>` or `io_context::strand`. All
+ event handler function objects need to be bound to the strand using
+ `asio::bind_executor()` or otherwise posted/dispatched through the strand
+ object.
+
+In the case of composed asynchronous operations, such as `async_read()` or
+`async_read_until()`, if a completion handler goes through a strand, then all
+intermediate handlers should also go through the same strand. This is needed to
+ensure thread safe access for any objects that are shared between the caller
+and the composed operation (in the case of `async_read()` it's the socket,
+which the caller can `close()` to cancel the operation).
+
+This is done by partially specialising the `asio::ssociated_executor<>` trait
+for all intermediate handlers. This trait forwards to the corresponding trait
+specialisation for the final handler:
+
+ struct my_handler
+ {
+ void operator()() { ... }
+ };
+
+ namespace asio {
+
+ template <class Executor>
+ struct associated_executor<my_handler, Executor>
+ {
+ // Custom implementation of Executor type requirements.
+ typedef my_executor type;
+
+ // Return a custom executor implementation.
+ static type get(const my_handler&, const Executor& = Executor())
+ {
+ return my_executor();
+ }
+ };
+
+ } // namespace asio
+
+The `asio::bind_executor()` function is a helper to bind a specific executor
+object, such as a strand, to a completion handler. This binding automatically
+specialises the `associated_executor` trait as shown above. For example, to
+bind a strand to a completion handler we would simply write:
+
+ my_socket.async_read_some(my_buffer,
+ asio::bind_executor(my_strand,
+ [](error_code ec, size_t length)
+ {
+ // ...
+ }));
+
+[heading See Also]
+
+[link asio.reference.bind_executor bind_executor],
+[link asio.reference.strand strand],
+[link asio.reference.io_context__strand io_context::strand],
+[link asio.tutorial.tuttimer5 tutorial Timer.5],
+[link asio.examples.cpp03_examples.http_server_3 HTTP server 3 example].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/streams.qbk b/3rdparty/asio/src/doc/overview/streams.qbk
new file mode 100644
index 00000000000..ea89e8b5d62
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/streams.qbk
@@ -0,0 +1,62 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:streams Streams, Short Reads and Short Writes]
+
+Many I/O objects in Asio are stream-oriented. This means that:
+
+* There are no message boundaries. The data being transferred is a continuous
+ sequence of bytes.
+
+* Read or write operations may transfer fewer bytes than requested. This is
+ referred to as a short read or short write.
+
+Objects that provide stream-oriented I/O model one or more of the following
+type requirements:
+
+* `SyncReadStream`, where synchronous read operations are performed using a
+ member function called `read_some()`.
+
+* `AsyncReadStream`, where asynchronous read operations are performed using a
+ member function called `async_read_some()`.
+
+* `SyncWriteStream`, where synchronous write operations are performed using a
+ member function called `write_some()`.
+
+* `AsyncWriteStream`, where synchronous write operations are performed using a
+ member function called `async_write_some()`.
+
+Examples of stream-oriented I/O objects include `ip::tcp::socket`,
+`ssl::stream<>`, `posix::stream_descriptor`, `windows::stream_handle`, etc.
+
+Programs typically want to transfer an exact number of bytes. When a short read
+or short write occurs the program must restart the operation, and continue to
+do so until the required number of bytes has been transferred. Asio provides
+generic functions that do this automatically: `read()`, `async_read()`,
+`write()` and `async_write()`.
+
+[heading Why EOF is an Error]
+
+* The end of a stream can cause `read`, `async_read`, `read_until` or
+ `async_read_until` functions to violate their contract. E.g.
+ a read of N bytes may finish early due to EOF.
+
+* An EOF error may be used to distinguish the end of a stream from a successful
+ read of size 0.
+
+[heading See Also]
+
+[link asio.reference.async_read async_read()],
+[link asio.reference.async_write async_write()],
+[link asio.reference.read read()],
+[link asio.reference.write write()],
+[link asio.reference.AsyncReadStream AsyncReadStream],
+[link asio.reference.AsyncWriteStream AsyncWriteStream],
+[link asio.reference.SyncReadStream SyncReadStream],
+[link asio.reference.SyncWriteStream SyncWriteStream].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/sync_op.dot b/3rdparty/asio/src/doc/overview/sync_op.dot
new file mode 100644
index 00000000000..f3eb4dd4008
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/sync_op.dot
@@ -0,0 +1,67 @@
+digraph g
+{
+ graph
+ [
+ nodesep="0.6"
+ ];
+
+ edge
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ labelfontname="Helvetica",
+ labelfontsize=10
+ ];
+
+ node
+ [
+ fontname="Helvetica",
+ fontsize=10,
+ shape=box
+ ];
+
+ edge
+ [
+ arrowhead="open"
+ ]
+
+ // Program elements.
+ {
+ operating_system [ label="Operating System", shape=ellipse ];
+ io_context [ label="io_context" ];
+ io_object [ label="I/O Object\ne.g. socket" ];
+ your_program [ label="Your Program" ];
+ }
+
+ // Owning relationships.
+ {
+ edge [ arrowtail="diamond" ];
+ your_program:w -> io_object:nw;
+ your_program:se -> io_context:ne;
+ }
+
+ // Non-owning relationships;
+ {
+ io_object:sw -> io_context:w;
+ }
+
+ // Actions.
+ {
+ edge [ style="dashed", color="#808080" ];
+
+ // Forward actions.
+ {
+ your_program:sw -> io_object:n [ label="1" ];
+ io_object:s -> io_context:nw [ label="2" ];
+ io_context:sw -> operating_system:nw [ label="3" ];
+ }
+
+ // Reverse actions.
+ {
+ edge [ arrowhead="none", arrowtail="open" ];
+ io_context:se -> operating_system:ne [ label="4" ];
+ io_object:se -> io_context:n [ label="5" ];
+ your_program:s -> io_object:ne [ label="6" ];
+ }
+ }
+}
diff --git a/3rdparty/asio/src/doc/overview/sync_op.png b/3rdparty/asio/src/doc/overview/sync_op.png
new file mode 100644
index 00000000000..a96c8351b9f
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/sync_op.png
Binary files differ
diff --git a/3rdparty/asio/src/doc/overview/threads.qbk b/3rdparty/asio/src/doc/overview/threads.qbk
new file mode 100644
index 00000000000..b5239d9828e
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/threads.qbk
@@ -0,0 +1,66 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:threads Threads and Asio]
+
+[heading Thread Safety]
+
+In general, it is safe to make concurrent use of distinct objects, but unsafe
+to make concurrent use of a single object. However, types such as `io_context`
+provide a stronger guarantee that it is safe to use a single object
+concurrently.
+
+[heading Thread Pools]
+
+Multiple threads may call `io_context::run()` to set up a pool of threads from
+which completion handlers may be invoked. This approach may also be used with
+`io_context::post()` to use a means to perform any computational tasks across a
+thread pool.
+
+Note that all threads that have joined an `io_context`'s pool are considered
+equivalent, and the `io_context` may distribute work across them in an
+arbitrary fashion.
+
+[heading Internal Threads]
+
+The implementation of this library for a particular platform may make use of
+one or more internal threads to emulate asynchronicity. As far as possible,
+these threads must be invisible to the library user. In particular, the threads:
+
+* must not call the user's code directly; and
+
+* must block all signals.
+
+This approach is complemented by the following guarantee:
+
+* Asynchronous completion handlers will only be called from threads that are
+ currently calling `io_context::run()`.
+
+Consequently, it is the library user's responsibility to create and manage all
+threads to which the notifications will be delivered.
+
+The reasons for this approach include:
+
+* By only calling `io_context::run()` from a single thread, the user's code can
+ avoid the development complexity associated with synchronisation. For
+ example, a library user can implement scalable servers that are
+ single-threaded (from the user's point of view).
+
+* A library user may need to perform initialisation in a thread shortly after
+ the thread starts and before any other application code is executed. For
+ example, users of Microsoft's COM must call `CoInitializeEx` before any other
+ COM operations can be called from that thread.
+
+* The library interface is decoupled from interfaces for thread creation and
+ management, and permits implementations on platforms where threads are not
+ available.
+
+[heading See Also]
+
+[link asio.reference.io_context io_context].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/timers.qbk b/3rdparty/asio/src/doc/overview/timers.qbk
new file mode 100644
index 00000000000..0c5528dcc1b
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/timers.qbk
@@ -0,0 +1,52 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:timers Timers]
+
+Long running I/O operations will often have a deadline by which they must have
+completed. These deadlines may be expressed as absolute times, but are often
+calculated relative to the current time.
+
+As a simple example, to perform a synchronous wait operation on a timer using a
+relative time one may write:
+
+ io_context i;
+ ...
+ deadline_timer t(i);
+ t.expires_from_now(boost::posix_time::seconds(5));
+ t.wait();
+
+More commonly, a program will perform an asynchronous wait operation on a
+timer:
+
+ void handler(asio::error_code ec) { ... }
+ ...
+ io_context i;
+ ...
+ deadline_timer t(i);
+ t.expires_from_now(boost::posix_time::milliseconds(400));
+ t.async_wait(handler);
+ ...
+ i.run();
+
+The deadline associated with a timer may also be obtained as a relative time:
+
+ boost::posix_time::time_duration time_until_expiry
+ = t.expires_from_now();
+
+or as an absolute time to allow composition of timers:
+
+ deadline_timer t2(i);
+ t2.expires_at(t.expires_at() + boost::posix_time::seconds(30));
+
+[heading See Also]
+
+[link asio.reference.basic_deadline_timer basic_deadline_timer],
+[link asio.reference.deadline_timer deadline_timer],
+[link asio.tutorial.tuttimer1 timer tutorials].
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/overview/windows.qbk b/3rdparty/asio/src/doc/overview/windows.qbk
new file mode 100644
index 00000000000..da49a0b409e
--- /dev/null
+++ b/3rdparty/asio/src/doc/overview/windows.qbk
@@ -0,0 +1,126 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:windows Windows-Specific Functionality]
+
+[link asio.overview.windows.stream_handle Stream-Oriented HANDLEs]
+
+[link asio.overview.windows.random_access_handle Random-Access HANDLEs]
+
+[link asio.overview.windows.object_handle Object HANDLEs]
+
+[section:stream_handle Stream-Oriented HANDLEs]
+
+Asio contains classes to allow asynchronous read and write operations to be
+performed on Windows `HANDLE`s, such as named pipes.
+
+For example, to perform asynchronous operations on a named pipe, the following
+object may be created:
+
+ HANDLE handle = ::CreateFile(...);
+ windows::stream_handle pipe(my_io_context, handle);
+
+These are then used as synchronous or asynchronous read and write streams. This
+means the objects can be used with any of the [link asio.reference.read
+read()], [link asio.reference.async_read async_read()], [link
+asio.reference.write write()], [link asio.reference.async_write
+async_write()], [link asio.reference.read_until read_until()] or [link
+asio.reference.async_read_until async_read_until()] free functions.
+
+The kernel object referred to by the `HANDLE` must support use with I/O
+completion ports (which means that named pipes are supported, but anonymous
+pipes and console streams are not).
+
+[heading See Also]
+
+[link asio.reference.windows__stream_handle windows::stream_handle].
+
+[heading Notes]
+
+Windows stream `HANDLE`s are only available at compile time when targeting
+Windows and only when the I/O completion port backend is used (which is the
+default). A program may test for the macro `ASIO_HAS_WINDOWS_STREAM_HANDLE` to
+determine whether they are supported.
+
+[endsect]
+
+[/-----------------------------------------------------------------------------]
+
+[section:random_access_handle Random-Access HANDLEs]
+
+Asio provides Windows-specific classes that permit asynchronous read and write
+operations to be performed on HANDLEs that refer to regular files.
+
+For example, to perform asynchronous operations on a file the following object
+may be created:
+
+ HANDLE handle = ::CreateFile(...);
+ windows::random_access_handle file(my_io_context, handle);
+
+Data may be read from or written to the handle using one of the
+`read_some_at()`, `async_read_some_at()`, `write_some_at()` or
+`async_write_some_at()` member functions. However, like the equivalent
+functions (`read_some()`, etc.) on streams, these functions are only required
+to transfer one or more bytes in a single operation. Therefore free functions
+called [link asio.reference.read_at read_at()], [link
+asio.reference.async_read_at async_read_at()], [link asio.reference.write_at
+write_at()] and [link asio.reference.async_write_at async_write_at()] have been
+created to repeatedly call the corresponding [^[**]_some_at()] function until
+all data has been transferred.
+
+[heading See Also]
+
+[link asio.reference.windows__random_access_handle windows::random_access_handle].
+
+[heading Notes]
+
+Windows random-access `HANDLE`s are only available at compile time when
+targeting Windows and only when the I/O completion port backend is used (which
+is the default). A program may test for the macro
+`ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE` to determine whether they are
+supported.
+
+[endsect]
+
+[/-----------------------------------------------------------------------------]
+
+[section:object_handle Object HANDLEs]
+
+Asio provides Windows-specific classes that permit asynchronous wait operations
+to be performed on HANDLEs to kernel objects of the following types:
+
+* Change notification
+* Console input
+* Event
+* Memory resource notification
+* Process
+* Semaphore
+* Thread
+* Waitable timer
+
+For example, to perform asynchronous operations on an event, the following
+object may be created:
+
+ HANDLE handle = ::CreateEvent(...);
+ windows::object_handle file(my_io_context, handle);
+
+The `wait()` and `async_wait()` member functions may then be used to wait until
+the kernel object is signalled.
+
+[heading See Also]
+
+[link asio.reference.windows__object_handle windows::object_handle].
+
+[heading Notes]
+
+Windows object `HANDLE`s are only available at compile time when targeting
+Windows. Programs may test for the macro `ASIO_HAS_WINDOWS_OBJECT_HANDLE` to
+determine whether they are supported.
+
+[endsect]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/project-root.jam b/3rdparty/asio/src/doc/project-root.jam
new file mode 100644
index 00000000000..218d8921e51
--- /dev/null
+++ b/3rdparty/asio/src/doc/project-root.jam
@@ -0,0 +1 @@
+# This file intentionally left blank.
diff --git a/3rdparty/asio/src/doc/quickref.xml b/3rdparty/asio/src/doc/quickref.xml
new file mode 100644
index 00000000000..7d2632a1fd9
--- /dev/null
+++ b/3rdparty/asio/src/doc/quickref.xml
@@ -0,0 +1,514 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../boost/tools/boostbook/dtd/boostbook.dtd">
+
+<!--
+ Copyright (c) 2003-2016 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)
+-->
+
+<informaltable frame="all">
+ <tgroup cols="4">
+ <colspec colname="a"/>
+ <colspec colname="b"/>
+ <colspec colname="c"/>
+ <colspec colname="d"/>
+ <thead>
+ <row>
+ <entry valign="center" namest="a" nameend="d">
+ <bridgehead renderas="sect2">Core</bridgehead>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.coroutine">coroutine</link></member>
+ <member><link linkend="asio.reference.error_code">error_code</link></member>
+ <member><link linkend="asio.reference.execution_context">execution_context</link></member>
+ <member><link linkend="asio.reference.execution_context__id">execution_context::id</link></member>
+ <member><link linkend="asio.reference.execution_context__service">execution_context::service</link></member>
+ <member><link linkend="asio.reference.executor">executor</link></member>
+ <member><link linkend="asio.reference.executor_arg_t">executor_arg_t</link></member>
+ <member><link linkend="asio.reference.invalid_service_owner">invalid_service_owner</link></member>
+ <member><link linkend="asio.reference.io_context">io_context</link></member>
+ <member><link linkend="asio.reference.io_context__executor_type">io_context::executor_type</link></member>
+ <member><link linkend="asio.reference.io_context__service">io_context::service</link></member>
+ <member><link linkend="asio.reference.io_context__strand">io_context::strand</link></member>
+ <member><link linkend="asio.reference.io_context__work">io_context::work</link> (deprecated)</member>
+ <member><link linkend="asio.reference.service_already_exists">service_already_exists</link></member>
+ <member><link linkend="asio.reference.system_error">system_error</link></member>
+ <member><link linkend="asio.reference.system_executor">system_executor</link></member>
+ <member><link linkend="asio.reference.thread">thread</link></member>
+ <member><link linkend="asio.reference.thread_pool">thread_pool</link></member>
+ <member><link linkend="asio.reference.thread_pool__executor_type">thread_pool::executor_type</link></member>
+ <member><link linkend="asio.reference.yield_context">yield_context</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Free Functions</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.add_service">add_service</link></member>
+ <member><link linkend="asio.reference.asio_handler_allocate">asio_handler_allocate</link></member>
+ <member><link linkend="asio.reference.asio_handler_deallocate">asio_handler_deallocate</link></member>
+ <member><link linkend="asio.reference.asio_handler_invoke">asio_handler_invoke</link></member>
+ <member><link linkend="asio.reference.asio_handler_is_continuation">asio_handler_is_continuation</link></member>
+ <member><link linkend="asio.reference.bind_executor">bind_executor</link></member>
+ <member><link linkend="asio.reference.dispatch">dispatch</link></member>
+ <member><link linkend="asio.reference.defer">defer</link></member>
+ <member><link linkend="asio.reference.get_associated_allocator">get_associated_allocator</link></member>
+ <member><link linkend="asio.reference.get_associated_executor">get_associated_executor</link></member>
+ <member><link linkend="asio.reference.has_service">has_service</link></member>
+ <member><link linkend="asio.reference.make_work_guard">make_work_guard</link></member>
+ <member><link linkend="asio.reference.post">post</link></member>
+ <member><link linkend="asio.reference.spawn">spawn</link></member>
+ <member><link linkend="asio.reference.use_service">use_service</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.async_completion">async_completion</link></member>
+ <member><link linkend="asio.reference.basic_io_object">basic_io_object</link></member>
+ <member><link linkend="asio.reference.basic_yield_context">basic_yield_context</link></member>
+ <member><link linkend="asio.reference.executor_binder">executor_binder</link></member>
+ <member><link linkend="asio.reference.executor_work_guard">executor_work_guard</link></member>
+ <member><link linkend="asio.reference.strand">strand</link></member>
+ <member><link linkend="asio.reference.use_future_t">use_future_t</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Special Values</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.executor_arg">executor_arg</link></member>
+ <member><link linkend="asio.reference.use_future">use_future</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Boost.Bind Placeholders</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.placeholders__bytes_transferred">placeholders::bytes_transferred</link></member>
+ <member><link linkend="asio.reference.placeholders__endpoint">placeholders::endpoint</link></member>
+ <member><link linkend="asio.reference.placeholders__error">placeholders::error</link></member>
+ <member><link linkend="asio.reference.placeholders__iterator">placeholders::iterator</link></member>
+ <member><link linkend="asio.reference.placeholders__results">placeholders::results</link></member>
+ <member><link linkend="asio.reference.placeholders__signal_number">placeholders::signal_number</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Error Codes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.error__basic_errors">error::basic_errors</link></member>
+ <member><link linkend="asio.reference.error__netdb_errors">error::netdb_errors</link></member>
+ <member><link linkend="asio.reference.error__addrinfo_errors">error::addrinfo_errors</link></member>
+ <member><link linkend="asio.reference.error__misc_errors">error::misc_errors</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Traits</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.associated_allocator">associated_allocator</link></member>
+ <member><link linkend="asio.reference.associated_executor">associated_executor</link></member>
+ <member><link linkend="asio.reference.async_result">async_result</link></member>
+ <member><link linkend="asio.reference.handler_type">handler_type </link> (deprecated)</member>
+ <member><link linkend="asio.reference.is_executor">is_executor</link></member>
+ <member><link linkend="asio.reference.uses_executor">uses_executor</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.asynchronous_operations">Asynchronous operations</link></member>
+ <member><link linkend="asio.reference.CompletionHandler">CompletionHandler</link></member>
+ <member><link linkend="asio.reference.ExecutionContext">ExecutionContext</link></member>
+ <member><link linkend="asio.reference.Executor1">Executor</link></member>
+ <member><link linkend="asio.reference.Handler">Handler</link></member>
+ <member><link linkend="asio.reference.Service">Service</link></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <tgroup cols="4">
+ <colspec colname="a"/>
+ <colspec colname="b"/>
+ <colspec colname="c"/>
+ <colspec colname="d"/>
+ <thead>
+ <row>
+ <entry valign="center" namest="a" nameend="d">
+ <bridgehead renderas="sect2">Buffers and Buffer-Oriented Operations</bridgehead>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.const_buffer">const_buffer</link></member>
+ <member><link linkend="asio.reference.mutable_buffer">mutable_buffer</link></member>
+ <member><link linkend="asio.reference.const_buffers_1">const_buffers_1 </link> (deprecated)</member>
+ <member><link linkend="asio.reference.mutable_buffers_1">mutable_buffers_1 </link> (deprecated)</member>
+ <member><link linkend="asio.reference.null_buffers">null_buffers</link> (deprecated)</member>
+ <member><link linkend="asio.reference.streambuf">streambuf</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.basic_streambuf">basic_streambuf</link></member>
+ <member><link linkend="asio.reference.buffered_read_stream">buffered_read_stream</link></member>
+ <member><link linkend="asio.reference.buffered_stream">buffered_stream</link></member>
+ <member><link linkend="asio.reference.buffered_write_stream">buffered_write_stream</link></member>
+ <member><link linkend="asio.reference.buffers_iterator">buffers_iterator</link></member>
+ <member><link linkend="asio.reference.dynamic_string_buffer">dynamic_string_buffer</link></member>
+ <member><link linkend="asio.reference.dynamic_vector_buffer">dynamic_vector_buffer</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Free Functions</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.async_read">async_read</link></member>
+ <member><link linkend="asio.reference.async_read_at">async_read_at</link></member>
+ <member><link linkend="asio.reference.async_read_until">async_read_until</link></member>
+ <member><link linkend="asio.reference.async_write">async_write</link></member>
+ <member><link linkend="asio.reference.async_write_at">async_write_at</link></member>
+ <member><link linkend="asio.reference.buffer">buffer</link></member>
+ <member><link linkend="asio.reference.buffer_cast">buffer_cast </link> (deprecated)</member>
+ <member><link linkend="asio.reference.buffer_copy">buffer_copy</link></member>
+ <member><link linkend="asio.reference.buffer_size">buffer_size</link></member>
+ <member><link linkend="asio.reference.buffers_begin">buffers_begin</link></member>
+ <member><link linkend="asio.reference.buffers_end">buffers_end</link></member>
+ <member><link linkend="asio.reference.dynamic_buffer">dynamic_buffer</link></member>
+ <member><link linkend="asio.reference.read">read</link></member>
+ <member><link linkend="asio.reference.read_at">read_at</link></member>
+ <member><link linkend="asio.reference.read_until">read_until</link></member>
+ <member><link linkend="asio.reference.transfer_all">transfer_all</link></member>
+ <member><link linkend="asio.reference.transfer_at_least">transfer_at_least</link></member>
+ <member><link linkend="asio.reference.transfer_exactly">transfer_exactly</link></member>
+ <member><link linkend="asio.reference.write">write</link></member>
+ <member><link linkend="asio.reference.write_at">write_at</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Type Traits</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.is_const_buffer_sequence">is_const_buffer_sequence</link></member>
+ <member><link linkend="asio.reference.is_match_condition">is_match_condition</link></member>
+ <member><link linkend="asio.reference.is_mutable_buffer_sequence">is_mutable_buffer_sequence</link></member>
+ <member><link linkend="asio.reference.is_read_buffered">is_read_buffered</link></member>
+ <member><link linkend="asio.reference.is_write_buffered">is_write_buffered</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.read_write_operations">Read and write operations</link></member>
+ <member><link linkend="asio.reference.AsyncRandomAccessReadDevice">AsyncRandomAccessReadDevice</link></member>
+ <member><link linkend="asio.reference.AsyncRandomAccessWriteDevice">AsyncRandomAccessWriteDevice</link></member>
+ <member><link linkend="asio.reference.AsyncReadStream">AsyncReadStream</link></member>
+ <member><link linkend="asio.reference.AsyncWriteStream">AsyncWriteStream</link></member>
+ <member><link linkend="asio.reference.CompletionCondition">CompletionCondition</link></member>
+ <member><link linkend="asio.reference.ConstBufferSequence">ConstBufferSequence</link></member>
+ <member><link linkend="asio.reference.DynamicBuffer">DynamicBuffer</link></member>
+ <member><link linkend="asio.reference.MutableBufferSequence">MutableBufferSequence</link></member>
+ <member><link linkend="asio.reference.ReadHandler">ReadHandler</link></member>
+ <member><link linkend="asio.reference.SyncRandomAccessReadDevice">SyncRandomAccessReadDevice</link></member>
+ <member><link linkend="asio.reference.SyncRandomAccessWriteDevice">SyncRandomAccessWriteDevice</link></member>
+ <member><link linkend="asio.reference.SyncReadStream">SyncReadStream</link></member>
+ <member><link linkend="asio.reference.SyncWriteStream">SyncWriteStream</link></member>
+ <member><link linkend="asio.reference.WriteHandler">WriteHandler</link></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <tgroup cols="4">
+ <colspec colname="a"/>
+ <colspec colname="b"/>
+ <colspec colname="c"/>
+ <colspec colname="d"/>
+ <thead>
+ <row>
+ <entry valign="center" namest="a" nameend="d">
+ <bridgehead renderas="sect2">Networking</bridgehead>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.generic__datagram_protocol">generic::datagram_protocol</link></member>
+ <member><link linkend="asio.reference.generic__datagram_protocol.endpoint">generic::datagram_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.generic__datagram_protocol.socket">generic::datagram_protocol::socket</link></member>
+ <member><link linkend="asio.reference.generic__raw_protocol">generic::raw_protocol</link></member>
+ <member><link linkend="asio.reference.generic__raw_protocol.endpoint">generic::raw_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.generic__raw_protocol.socket">generic::raw_protocol::socket</link></member>
+ <member><link linkend="asio.reference.generic__seq_packet_protocol">generic::seq_packet_protocol</link></member>
+ <member><link linkend="asio.reference.generic__seq_packet_protocol.endpoint">generic::seq_packet_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.generic__seq_packet_protocol.socket">generic::seq_packet_protocol::socket</link></member>
+ <member><link linkend="asio.reference.generic__stream_protocol">generic::stream_protocol</link></member>
+ <member><link linkend="asio.reference.generic__stream_protocol.endpoint">generic::stream_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.generic__stream_protocol.iostream">generic::stream_protocol::iostream</link></member>
+ <member><link linkend="asio.reference.generic__stream_protocol.socket">generic::stream_protocol::socket</link></member>
+ <member><link linkend="asio.reference.ip__address">ip::address</link></member>
+ <member><link linkend="asio.reference.ip__address_v4">ip::address_v4</link></member>
+ <member><link linkend="asio.reference.ip__address_v4_iterator">ip::address_v4_iterator</link></member>
+ <member><link linkend="asio.reference.ip__address_v4_range">ip::address_v4_range</link></member>
+ <member><link linkend="asio.reference.ip__address_v6">ip::address_v6</link></member>
+ <member><link linkend="asio.reference.ip__address_v6_iterator">ip::address_v6_iterator</link></member>
+ <member><link linkend="asio.reference.ip__address_v6_range">ip::address_v6_range</link></member>
+ <member><link linkend="asio.reference.ip__icmp">ip::icmp</link></member>
+ <member><link linkend="asio.reference.ip__icmp.endpoint">ip::icmp::endpoint</link></member>
+ <member><link linkend="asio.reference.ip__icmp.resolver">ip::icmp::resolver</link></member>
+ <member><link linkend="asio.reference.ip__icmp.socket">ip::icmp::socket</link></member>
+ <member><link linkend="asio.reference.ip__network_v4">ip::network_v4</link></member>
+ <member><link linkend="asio.reference.ip__network_v6">ip::network_v6</link></member>
+ <member><link linkend="asio.reference.ip__resolver_query_base">ip::resolver_query_base</link></member>
+ <member><link linkend="asio.reference.ip__tcp">ip::tcp</link></member>
+ <member><link linkend="asio.reference.ip__tcp.acceptor">ip::tcp::acceptor</link></member>
+ <member><link linkend="asio.reference.ip__tcp.endpoint">ip::tcp::endpoint</link></member>
+ <member><link linkend="asio.reference.ip__tcp.iostream">ip::tcp::iostream</link></member>
+ <member><link linkend="asio.reference.ip__tcp.resolver">ip::tcp::resolver</link></member>
+ <member><link linkend="asio.reference.ip__tcp.socket">ip::tcp::socket</link></member>
+ <member><link linkend="asio.reference.ip__udp">ip::udp</link></member>
+ <member><link linkend="asio.reference.ip__udp.endpoint">ip::udp::endpoint</link></member>
+ <member><link linkend="asio.reference.ip__udp.resolver">ip::udp::resolver</link></member>
+ <member><link linkend="asio.reference.ip__udp.socket">ip::udp::socket</link></member>
+ <member><link linkend="asio.reference.socket_base">socket_base</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Free Functions</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.async_connect">async_connect</link></member>
+ <member><link linkend="asio.reference.connect">connect</link></member>
+ <member><link linkend="asio.reference.ip__host_name">ip::host_name</link></member>
+ <member><link linkend="asio.reference.ip__address.make_address">ip::make_address</link></member>
+ <member><link linkend="asio.reference.ip__address_v4.make_address_v4">ip::make_address_v4</link></member>
+ <member><link linkend="asio.reference.ip__address_v6.make_address_v6">ip::make_address_v6</link></member>
+ <member><link linkend="asio.reference.ip__network_v4.make_network_v4">ip::make_network_v4</link></member>
+ <member><link linkend="asio.reference.ip__network_v6.make_network_v6">ip::make_network_v6</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.basic_datagram_socket">basic_datagram_socket</link></member>
+ <member><link linkend="asio.reference.basic_raw_socket">basic_raw_socket</link></member>
+ <member><link linkend="asio.reference.basic_seq_packet_socket">basic_seq_packet_socket</link></member>
+ <member><link linkend="asio.reference.basic_socket">basic_socket</link></member>
+ <member><link linkend="asio.reference.basic_socket_acceptor">basic_socket_acceptor</link></member>
+ <member><link linkend="asio.reference.basic_socket_iostream">basic_socket_iostream</link></member>
+ <member><link linkend="asio.reference.basic_socket_streambuf">basic_socket_streambuf</link></member>
+ <member><link linkend="asio.reference.basic_stream_socket">basic_stream_socket</link></member>
+ <member><link linkend="asio.reference.generic__basic_endpoint">generic::basic_endpoint</link></member>
+ <member><link linkend="asio.reference.ip__basic_endpoint">ip::basic_endpoint</link></member>
+ <member><link linkend="asio.reference.ip__basic_resolver">ip::basic_resolver</link></member>
+ <member><link linkend="asio.reference.ip__basic_resolver_entry">ip::basic_resolver_entry</link></member>
+ <member><link linkend="asio.reference.ip__basic_resolver_iterator">ip::basic_resolver_iterator</link></member>
+ <member><link linkend="asio.reference.ip__basic_resolver_query">ip::basic_resolver_query</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Socket Options</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.ip__multicast__enable_loopback">ip::multicast::enable_loopback</link></member>
+ <member><link linkend="asio.reference.ip__multicast__hops">ip::multicast::hops</link></member>
+ <member><link linkend="asio.reference.ip__multicast__join_group">ip::multicast::join_group</link></member>
+ <member><link linkend="asio.reference.ip__multicast__leave_group">ip::multicast::leave_group</link></member>
+ <member><link linkend="asio.reference.ip__multicast__outbound_interface">ip::multicast::outbound_interface</link></member>
+ <member><link linkend="asio.reference.ip__tcp.no_delay">ip::tcp::no_delay</link></member>
+ <member><link linkend="asio.reference.ip__unicast__hops">ip::unicast::hops</link></member>
+ <member><link linkend="asio.reference.ip__v6_only">ip::v6_only</link></member>
+ <member><link linkend="asio.reference.socket_base.broadcast">socket_base::broadcast</link></member>
+ <member><link linkend="asio.reference.socket_base.debug">socket_base::debug</link></member>
+ <member><link linkend="asio.reference.socket_base.do_not_route">socket_base::do_not_route</link></member>
+ <member><link linkend="asio.reference.socket_base.enable_connection_aborted">socket_base::enable_connection_aborted</link></member>
+ <member><link linkend="asio.reference.socket_base.keep_alive">socket_base::keep_alive</link></member>
+ <member><link linkend="asio.reference.socket_base.linger">socket_base::linger</link></member>
+ <member><link linkend="asio.reference.socket_base.receive_buffer_size">socket_base::receive_buffer_size</link></member>
+ <member><link linkend="asio.reference.socket_base.receive_low_watermark">socket_base::receive_low_watermark</link></member>
+ <member><link linkend="asio.reference.socket_base.reuse_address">socket_base::reuse_address</link></member>
+ <member><link linkend="asio.reference.socket_base.send_buffer_size">socket_base::send_buffer_size</link></member>
+ <member><link linkend="asio.reference.socket_base.send_low_watermark">socket_base::send_low_watermark</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">I/O Control Commands</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.socket_base.bytes_readable">socket_base::bytes_readable</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.synchronous_socket_operations">Synchronous socket operations</link></member>
+ <member><link linkend="asio.reference.asynchronous_socket_operations">Asynchronous socket operations</link></member>
+ <member><link linkend="asio.reference.AcceptableProtocol">AcceptableProtocol</link></member>
+ <member><link linkend="asio.reference.AcceptHandler">AcceptHandler</link></member>
+ <member><link linkend="asio.reference.ConnectCondition">ConnectCondition</link></member>
+ <member><link linkend="asio.reference.ConnectHandler">ConnectHandler</link></member>
+ <member><link linkend="asio.reference.Endpoint">Endpoint</link></member>
+ <member><link linkend="asio.reference.EndpointSequence">EndpointSequence</link></member>
+ <member><link linkend="asio.reference.GettableSocketOption">GettableSocketOption</link></member>
+ <member><link linkend="asio.reference.InternetProtocol">InternetProtocol</link></member>
+ <member><link linkend="asio.reference.IoControlCommand">IoControlCommand</link></member>
+ <member><link linkend="asio.reference.IteratorConnectHandler">IteratorConnectHandler</link></member>
+ <member><link linkend="asio.reference.MoveAcceptHandler">MoveAcceptHandler</link></member>
+ <member><link linkend="asio.reference.Protocol">Protocol</link></member>
+ <member><link linkend="asio.reference.RangeConnectHandler">RangeConnectHandler</link></member>
+ <member><link linkend="asio.reference.ResolveHandler">ResolveHandler</link></member>
+ <member><link linkend="asio.reference.SettableSocketOption">SettableSocketOption</link></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <tgroup cols="4">
+ <colspec colname="a"/>
+ <colspec colname="b"/>
+ <colspec colname="c"/>
+ <colspec colname="d"/>
+ <thead>
+ <row>
+ <entry valign="center" namest="a" nameend="a">
+ <bridgehead renderas="sect2">Timers</bridgehead>
+ </entry>
+ <entry valign="center" namest="b" nameend="b">
+ <bridgehead renderas="sect2">SSL</bridgehead>
+ </entry>
+ <entry valign="center" namest="c" nameend="c">
+ <bridgehead renderas="sect2">Serial Ports</bridgehead>
+ </entry>
+ <entry valign="center" namest="d" nameend="d">
+ <bridgehead renderas="sect2">Signal Handling</bridgehead>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.deadline_timer">deadline_timer</link></member>
+ <member><link linkend="asio.reference.high_resolution_timer">high_resolution_timer</link></member>
+ <member><link linkend="asio.reference.steady_timer">steady_timer</link></member>
+ <member><link linkend="asio.reference.system_timer">system_timer</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.basic_deadline_timer">basic_deadline_timer</link></member>
+ <member><link linkend="asio.reference.basic_waitable_timer">basic_waitable_timer</link></member>
+ <member><link linkend="asio.reference.time_traits_lt__ptime__gt_">time_traits</link></member>
+ <member><link linkend="asio.reference.wait_traits">wait_traits</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.TimeTraits">TimeTraits</link></member>
+ <member><link linkend="asio.reference.WaitHandler">WaitHandler</link></member>
+ <member><link linkend="asio.reference.WaitTraits">WaitTraits</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.ssl__context">ssl::context</link></member>
+ <member><link linkend="asio.reference.ssl__context_base">ssl::context_base</link></member>
+ <member><link linkend="asio.reference.ssl__rfc2818_verification">ssl::rfc2818_verification</link></member>
+ <member><link linkend="asio.reference.ssl__stream_base">ssl::stream_base</link></member>
+ <member><link linkend="asio.reference.ssl__verify_context">ssl::verify_context</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.ssl__stream">ssl::stream</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.BufferedHandshakeHandler">BufferedHandshakeHandler</link></member>
+ <member><link linkend="asio.reference.HandshakeHandler">HandshakeHandler</link></member>
+ <member><link linkend="asio.reference.ShutdownHandler">ShutdownHandler</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.serial_port">serial_port</link></member>
+ <member><link linkend="asio.reference.serial_port_base">serial_port_base</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Serial Port Options</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.serial_port_base__baud_rate">serial_port_base::baud_rate</link></member>
+ <member><link linkend="asio.reference.serial_port_base__flow_control">serial_port_base::flow_control</link></member>
+ <member><link linkend="asio.reference.serial_port_base__parity">serial_port_base::parity</link></member>
+ <member><link linkend="asio.reference.serial_port_base__stop_bits">serial_port_base::stop_bits</link></member>
+ <member><link linkend="asio.reference.serial_port_base__character_size">serial_port_base::character_size</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.GettableSerialPortOption">GettableSerialPortOption</link></member>
+ <member><link linkend="asio.reference.SettableSerialPortOption">SettableSerialPortOption</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.signal_set">signal_set</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Type Requirements</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.SignalHandler">SignalHandler</link></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ <tgroup cols="4">
+ <colspec colname="a"/>
+ <colspec colname="b"/>
+ <colspec colname="c"/>
+ <colspec colname="d"/>
+ <thead>
+ <row>
+ <entry valign="center" namest="a" nameend="b">
+ <bridgehead renderas="sect2">POSIX-specific</bridgehead>
+ </entry>
+ <entry valign="center" namest="c" nameend="d">
+ <bridgehead renderas="sect2">Windows-specific</bridgehead>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.local__stream_protocol">local::stream_protocol</link></member>
+ <member><link linkend="asio.reference.local__stream_protocol.acceptor">local::stream_protocol::acceptor</link></member>
+ <member><link linkend="asio.reference.local__stream_protocol.endpoint">local::stream_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.local__stream_protocol.iostream">local::stream_protocol::iostream</link></member>
+ <member><link linkend="asio.reference.local__stream_protocol.socket">local::stream_protocol::socket</link></member>
+ <member><link linkend="asio.reference.local__datagram_protocol">local::datagram_protocol</link></member>
+ <member><link linkend="asio.reference.local__datagram_protocol.endpoint">local::datagram_protocol::endpoint</link></member>
+ <member><link linkend="asio.reference.local__datagram_protocol.socket">local::datagram_protocol::socket</link></member>
+ <member><link linkend="asio.reference.posix__descriptor">posix::descriptor</link></member>
+ <member><link linkend="asio.reference.posix__descriptor_base">posix::descriptor_base</link></member>
+ <member><link linkend="asio.reference.posix__stream_descriptor">posix::stream_descriptor</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top">
+ <bridgehead renderas="sect3">Free Functions</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.local__connect_pair">local::connect_pair</link></member>
+ </simplelist>
+ <bridgehead renderas="sect3">Class Templates</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.local__basic_endpoint">local::basic_endpoint</link></member>
+ </simplelist>
+ </entry>
+ <entry valign="top" namest="c" nameend="d">
+ <bridgehead renderas="sect3">Classes</bridgehead>
+ <simplelist type="vert" columns="1">
+ <member><link linkend="asio.reference.windows__object_handle">windows::object_handle</link></member>
+ <member><link linkend="asio.reference.windows__overlapped_handle">windows::overlapped_handle</link></member>
+ <member><link linkend="asio.reference.windows__overlapped_ptr">windows::overlapped_ptr</link></member>
+ <member><link linkend="asio.reference.windows__random_access_handle">windows::random_access_handle</link></member>
+ <member><link linkend="asio.reference.windows__stream_handle">windows::stream_handle</link></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
diff --git a/3rdparty/asio/src/doc/reference.dox b/3rdparty/asio/src/doc/reference.dox
new file mode 100644
index 00000000000..d0d56779840
--- /dev/null
+++ b/3rdparty/asio/src/doc/reference.dox
@@ -0,0 +1,256 @@
+# Doxyfile 1.4.5
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "Asio Reference"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = .
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = ./../../include/
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ./../../include/asio.hpp \
+ ./../../include/asio \
+ ./../../include/asio/generic \
+ ./../../include/asio/impl \
+ ./../../include/asio/ip \
+ ./../../include/asio/local \
+ ./../../include/asio/posix \
+ ./../../include/asio/ssl \
+ ./../../include/asio/windows \
+ ./noncopyable_dox.txt \
+ ./std_exception_dox.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = GENERATING_DOCUMENTATION \
+ ASIO_SOCKET_ERROR(e)=implementation_defined \
+ ASIO_NETDB_ERROR(e)=implementation_defined \
+ ASIO_EOF_ERROR(e)=implementation_defined \
+ ASIO_OS_ERROR(e1,e2)=implementation_defined \
+ ASIO_MOVE_ARG(a)=a&& \
+ ASIO_DECL= \
+ ASIO_CONSTEXPR=constexpr \
+ ASIO_NOEXCEPT=noexcept \
+ ASIO_INITFN_RESULT_TYPE(t,a)=void_or_deduced \
+ ASIO_SVC_TPARAM= \
+ ASIO_SVC_TPARAM_DEF1()= \
+ ASIO_SVC_TPARAM_DEF2()= \
+ ASIO_SVC_TARG= \
+ ASIO_SVC_TPARAM1= \
+ ASIO_SVC_TPARAM1_DEF1()= \
+ ASIO_SVC_TPARAM1_DEF2()= \
+ ASIO_SVC_TARG1= \
+ ASIO_SVC_T=asio::detail::service \
+ ASIO_SVC_T1=asio::detail::service \
+ ASIO_CONST_BUFFER=const_buffer \
+ ASIO_MUTABLE_BUFFER=mutable_buffer \
+ ASIO_SYNC_OP_VOID=void \
+ ASIO_STRING_VIEW_PARAM=string_view
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE = reference.tags
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = NO
+GROUP_GRAPHS = NO
+UML_LOOK = NO
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = NO
+INCLUDED_BY_GRAPH = NO
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = NO
+DIRECTORY_GRAPH = NO
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 640
+MAX_DOT_GRAPH_HEIGHT = 640
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = NO
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/3rdparty/asio/src/doc/reference.qbk b/3rdparty/asio/src/doc/reference.qbk
new file mode 100644
index 00000000000..7b9eb6441e2
--- /dev/null
+++ b/3rdparty/asio/src/doc/reference.qbk
@@ -0,0 +1,112844 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:reference Reference]
+
+[xinclude quickref.xml]
+
+[include requirements/asynchronous_operations.qbk]
+[include requirements/read_write_operations.qbk]
+[include requirements/synchronous_socket_operations.qbk]
+[include requirements/asynchronous_socket_operations.qbk]
+[include requirements/AcceptableProtocol.qbk]
+[include requirements/AcceptHandler.qbk]
+[include requirements/AsyncRandomAccessReadDevice.qbk]
+[include requirements/AsyncRandomAccessWriteDevice.qbk]
+[include requirements/AsyncReadStream.qbk]
+[include requirements/AsyncWriteStream.qbk]
+[include requirements/BufferedHandshakeHandler.qbk]
+[include requirements/CompletionCondition.qbk]
+[include requirements/CompletionHandler.qbk]
+[include requirements/ConnectCondition.qbk]
+[include requirements/ConnectHandler.qbk]
+[include requirements/ConstBufferSequence.qbk]
+[include requirements/DynamicBuffer.qbk]
+[include requirements/Endpoint.qbk]
+[include requirements/EndpointSequence.qbk]
+[include requirements/ExecutionContext.qbk]
+[include requirements/Executor.qbk]
+[include requirements/GettableSerialPortOption.qbk]
+[include requirements/GettableSocketOption.qbk]
+[include requirements/Handler.qbk]
+[include requirements/HandshakeHandler.qbk]
+[include requirements/InternetProtocol.qbk]
+[include requirements/IoControlCommand.qbk]
+[include requirements/IoObjectService.qbk]
+[include requirements/IteratorConnectHandler.qbk]
+[include requirements/MoveAcceptHandler.qbk]
+[include requirements/MutableBufferSequence.qbk]
+[include requirements/ProtoAllocator.qbk]
+[include requirements/Protocol.qbk]
+[include requirements/RangeConnectHandler.qbk]
+[include requirements/ReadHandler.qbk]
+[include requirements/ResolveHandler.qbk]
+[include requirements/Service.qbk]
+[include requirements/SettableSerialPortOption.qbk]
+[include requirements/SettableSocketOption.qbk]
+[include requirements/ShutdownHandler.qbk]
+[include requirements/SignalHandler.qbk]
+[include requirements/SyncRandomAccessReadDevice.qbk]
+[include requirements/SyncRandomAccessWriteDevice.qbk]
+[include requirements/SyncReadStream.qbk]
+[include requirements/SyncWriteStream.qbk]
+[include requirements/TimeTraits.qbk]
+[include requirements/WaitHandler.qbk]
+[include requirements/WaitTraits.qbk]
+[include requirements/WriteHandler.qbk]
+
+
+
+[section:add_service add_service]
+
+[indexterm1 asio.indexterm.add_service..add_service]
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ void add_service(
+ execution_context & e,
+ Service * svc);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[svc][The service object. On success, ownership of the service object is transferred to the [link asio.reference.execution_context `execution_context`]. When the [link asio.reference.execution_context `execution_context`] object is destroyed, it will destroy the service object by performing:
+``
+ delete static_cast<execution_context::service*>(svc)
+``
+]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`].]]
+
+[[asio::invalid_service_owner][Thrown if the service's owning [link asio.reference.execution_context `execution_context`] is not the [link asio.reference.execution_context `execution_context`] object specified by the `e` parameter. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/impl/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:asio_handler_allocate asio_handler_allocate]
+
+[indexterm1 asio.indexterm.asio_handler_allocate..asio_handler_allocate]
+Default allocation function for handlers.
+
+
+ void * asio_handler_allocate(
+ std::size_t size,
+ ... );
+
+
+Asynchronous operations may need to allocate temporary objects. Since asynchronous operations have a handler function object, these temporary objects can be said to be associated with the handler.
+
+Implement asio\_handler\_allocate and asio\_handler\_deallocate for your own handlers to provide custom allocation for these temporary objects.
+
+The default implementation of these allocation hooks uses `operator new` and `operator delete`.
+
+
+[heading Remarks]
+
+All temporary objects associated with a handler will be deallocated before the upcall to the handler is performed. This allows the same memory to be reused for a subsequent asynchronous operation initiated by the handler.
+
+
+[heading Example]
+
+
+
+ class my_handler;
+
+ void* asio_handler_allocate(std::size_t size, my_handler* context)
+ {
+ return ::operator new(size);
+ }
+
+ void asio_handler_deallocate(void* pointer, std::size_t size,
+ my_handler* context)
+ {
+ ::operator delete(pointer);
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/handler_alloc_hook.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:asio_handler_deallocate asio_handler_deallocate]
+
+[indexterm1 asio.indexterm.asio_handler_deallocate..asio_handler_deallocate]
+Default deallocation function for handlers.
+
+
+ void asio_handler_deallocate(
+ void * pointer,
+ std::size_t size,
+ ... );
+
+
+Implement asio\_handler\_allocate and asio\_handler\_deallocate for your own handlers to provide custom allocation for the associated temporary objects.
+
+The default implementation of these allocation hooks uses `operator new` and `operator delete`.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/handler_alloc_hook.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:asio_handler_invoke asio_handler_invoke]
+
+[indexterm1 asio.indexterm.asio_handler_invoke..asio_handler_invoke]
+Default invoke function for handlers.
+
+
+ template<
+ typename Function>
+ void ``[link asio.reference.asio_handler_invoke.overload1 asio_handler_invoke]``(
+ Function & function,
+ ... );
+ `` [''''&raquo;''' [link asio.reference.asio_handler_invoke.overload1 more...]]``
+
+ template<
+ typename Function>
+ void ``[link asio.reference.asio_handler_invoke.overload2 asio_handler_invoke]``(
+ const Function & function,
+ ... );
+ `` [''''&raquo;''' [link asio.reference.asio_handler_invoke.overload2 more...]]``
+
+Completion handlers for asynchronous operations are invoked by the [link asio.reference.io_context `io_context`] associated with the corresponding object (e.g. a socket or deadline\_timer). Certain guarantees are made on when the handler may be invoked, in particular that a handler can only be invoked from a thread that is currently calling `run()` on the corresponding [link asio.reference.io_context `io_context`] object. Handlers may subsequently be invoked through other objects (such as [link asio.reference.io_context__strand `io_context::strand`] objects) that provide additional guarantees.
+
+When asynchronous operations are composed from other asynchronous operations, all intermediate handlers should be invoked using the same method as the final handler. This is required to ensure that user-defined objects are not accessed in a way that may violate the guarantees. This hooking function ensures that the invoked method used for the final handler is accessible at each intermediate step.
+
+Implement asio\_handler\_invoke for your own handlers to specify a custom invocation strategy.
+
+This default implementation invokes the function object like so:
+
+ function();
+
+
+If necessary, the default implementation makes a copy of the function object so that the non-const operator() can be used.
+
+
+[heading Example]
+
+
+
+ class my_handler;
+
+ template <typename Function>
+ void asio_handler_invoke(Function function, my_handler* context)
+ {
+ context->strand_.dispatch(function);
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/handler_invoke_hook.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 asio_handler_invoke (1 of 2 overloads)]
+
+
+Default handler invocation hook used for non-const function objects.
+
+
+ template<
+ typename Function>
+ void asio_handler_invoke(
+ Function & function,
+ ... );
+
+
+
+[endsect]
+
+
+
+[section:overload2 asio_handler_invoke (2 of 2 overloads)]
+
+
+Default handler invocation hook used for const function objects.
+
+
+ template<
+ typename Function>
+ void asio_handler_invoke(
+ const Function & function,
+ ... );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:asio_handler_is_continuation asio_handler_is_continuation]
+
+[indexterm1 asio.indexterm.asio_handler_is_continuation..asio_handler_is_continuation]
+Default continuation function for handlers.
+
+
+ bool asio_handler_is_continuation(
+ ... );
+
+
+Asynchronous operations may represent a continuation of the asynchronous control flow associated with the current handler. The implementation can use this knowledge to optimise scheduling of the handler.
+
+Implement asio\_handler\_is\_continuation for your own handlers to indicate when a handler represents a continuation.
+
+The default implementation of the continuation hook returns `false`.
+
+
+[heading Example]
+
+
+
+ class my_handler;
+
+ bool asio_handler_is_continuation(my_handler* context)
+ {
+ return true;
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/handler_continuation_hook.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:associated_allocator associated_allocator]
+
+
+Traits type used to obtain the allocator associated with an object.
+
+
+ template<
+ typename T,
+ typename Allocator = std::allocator<void>>
+ struct associated_allocator
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.associated_allocator.type [*type]]]
+ [If T has a nested type allocator_type, T::allocator_type. Otherwise Allocator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.associated_allocator.get [*get]]]
+ [If T has a nested type allocator_type, returns t.get_allocator(). Otherwise returns a. ]
+ ]
+
+]
+
+A program may specialise this traits type if the `T` template parameter in the specialisation is a user-defined type. The template parameter `Allocator` shall be a type meeting the Allocator requirements.
+
+Specialisations shall meet the following requirements, where `t` is a const reference to an object of type `T`, and `a` is an object of type `Allocator`.
+
+
+* Provide a nested typedef `type` that identifies a type meeting the Allocator requirements.
+
+
+* Provide a noexcept static member function named `get`, callable as `get(t)` and with return type `type`.
+
+
+* Provide a noexcept static member function named `get`, callable as `get(t,a)` and with return type `type`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/associated_allocator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:get associated_allocator::get]
+
+[indexterm2 asio.indexterm.associated_allocator.get..get..associated_allocator]
+If `T` has a nested type `allocator_type`, returns `t.get_allocator()`. Otherwise returns `a`.
+
+
+ static type get(
+ const T & t,
+ const Allocator & a = Allocator());
+
+
+
+[endsect]
+
+
+
+[section:type associated_allocator::type]
+
+[indexterm2 asio.indexterm.associated_allocator.type..type..associated_allocator]
+If `T` has a nested type `allocator_type`, `T::allocator_type`. Otherwise `Allocator`.
+
+
+ typedef see_below type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/associated_allocator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:associated_executor associated_executor]
+
+
+Traits type used to obtain the executor associated with an object.
+
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]`` = system_executor>
+ struct associated_executor
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.associated_executor.type [*type]]]
+ [If T has a nested type executor_type, T::executor_type. Otherwise Executor. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.associated_executor.get [*get]]]
+ [If T has a nested type executor_type, returns t.get_executor(). Otherwise returns ex. ]
+ ]
+
+]
+
+A program may specialise this traits type if the `T` template parameter in the specialisation is a user-defined type. The template parameter `Executor` shall be a type meeting the Executor requirements.
+
+Specialisations shall meet the following requirements, where `t` is a const reference to an object of type `T`, and `e` is an object of type `Executor`.
+
+
+* Provide a nested typedef `type` that identifies a type meeting the Executor requirements.
+
+
+* Provide a noexcept static member function named `get`, callable as `get(t)` and with return type `type`.
+
+
+* Provide a noexcept static member function named `get`, callable as `get(t,e)` and with return type `type`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/associated_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:get associated_executor::get]
+
+[indexterm2 asio.indexterm.associated_executor.get..get..associated_executor]
+If `T` has a nested type `executor_type`, returns `t.get_executor()`. Otherwise returns `ex`.
+
+
+ static type get(
+ const T & t,
+ const Executor & ex = Executor());
+
+
+
+[endsect]
+
+
+
+[section:type associated_executor::type]
+
+[indexterm2 asio.indexterm.associated_executor.type..type..associated_executor]
+If `T` has a nested type `executor_type`, `T::executor_type`. Otherwise `Executor`.
+
+
+ typedef see_below type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/associated_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:async_completion async_completion]
+
+
+Helper template to deduce the handler type from a CompletionToken, capture a local copy of the handler, and then create an [link asio.reference.async_result `async_result`] for the handler.
+
+
+ template<
+ typename CompletionToken,
+ typename Signature>
+ struct async_completion
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.async_completion.completion_handler_type [*completion_handler_type]]]
+ [The real handler type to be used for the asynchronous operation. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_completion.async_completion [*async_completion]]]
+ [Constructor. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_completion.completion_handler [*completion_handler]]]
+ [A copy of, or reference to, a real handler object. ]
+ ]
+
+ [
+ [[link asio.reference.async_completion.result [*result]]]
+ [The result of the asynchronous operation's initiating function. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_completion async_completion::async_completion]
+
+[indexterm2 asio.indexterm.async_completion.async_completion..async_completion..async_completion]
+Constructor.
+
+
+ async_completion(
+ CompletionToken & token);
+
+
+The constructor creates the concrete completion handler and makes the link between the handler and the asynchronous result.
+
+
+[endsect]
+
+
+
+[section:completion_handler async_completion::completion_handler]
+
+[indexterm2 asio.indexterm.async_completion.completion_handler..completion_handler..async_completion]
+A copy of, or reference to, a real handler object.
+
+
+ conditional< is_same< CompletionToken, completion_handler_type >::value, completion_handler_type &, completion_handler_type >::type completion_handler;
+
+
+
+[endsect]
+
+
+
+[section:completion_handler_type async_completion::completion_handler_type]
+
+[indexterm2 asio.indexterm.async_completion.completion_handler_type..completion_handler_type..async_completion]
+The real handler type to be used for the asynchronous operation.
+
+
+ typedef asio::async_result< typename decay< CompletionToken >::type, Signature >::completion_handler_type completion_handler_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.async_result.completion_handler_type [*completion_handler_type]]]
+ [The concrete completion handler type for the specific signature. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.async_result.return_type [*return_type]]]
+ [The return type of the initiating function. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_result.async_result [*async_result]]]
+ [Construct an async result from a given handler. ]
+ ]
+
+ [
+ [[link asio.reference.async_result.get [*get]]]
+ [Obtain the value to be returned from the initiating function. ]
+ ]
+
+]
+
+The [link asio.reference.async_result `async_result`] traits class is used for determining:
+
+
+* the concrete completion handler type to be called at the end of the asynchronous operation;
+
+
+* the initiating function return type; and
+
+
+* 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.
+
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:result async_completion::result]
+
+[indexterm2 asio.indexterm.async_completion.result..result..async_completion]
+The result of the asynchronous operation's initiating function.
+
+
+ async_result< typename decay< CompletionToken >::type, Signature > result;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:async_connect async_connect]
+
+[indexterm1 asio.indexterm.async_connect..async_connect]
+Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.RangeConnectHandler RangeConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload1 async_connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ RangeConnectHandler && handler,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload2 async_connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ IteratorConnectHandler && handler,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload3 async_connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ IteratorConnectHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.RangeConnectHandler RangeConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload4 async_connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ RangeConnectHandler && handler,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload5 async_connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ IteratorConnectHandler && handler,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_connect.overload6 async_connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition,
+ IteratorConnectHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_connect.overload6 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/connect.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_connect (1 of 6 overloads)]
+
+
+Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.RangeConnectHandler RangeConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ RangeConnectHandler && handler,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, the successfully connected endpoint.
+ // Otherwise, a default-constructed endpoint.
+ const typename Protocol::endpoint& endpoint
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+
+ // ...
+
+ r.async_resolve(q, resolve_handler);
+
+ // ...
+
+ void resolve_handler(
+ const asio::error_code& ec,
+ tcp::resolver::results_type results)
+ {
+ if (!ec)
+ {
+ asio::async_connect(s, results, connect_handler);
+ }
+ }
+
+ // ...
+
+ void connect_handler(
+ const asio::error_code& ec,
+ const tcp::endpoint& endpoint)
+ {
+ // ...
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_connect (2 of 6 overloads)]
+
+
+(Deprecated.) Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ IteratorConnectHandler && handler,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, an iterator denoting the successfully
+ // connected endpoint. Otherwise, the end iterator.
+ Iterator iterator
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_connect (3 of 6 overloads)]
+
+
+Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ IteratorConnectHandler && handler);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, an iterator denoting the successfully
+ // connected endpoint. Otherwise, the end iterator.
+ Iterator iterator
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ std::vector<tcp::endpoint> endpoints = ...;
+ tcp::socket s(io_context);
+ asio::async_connect(s,
+ endpoints.begin(), endpoints.end(),
+ connect_handler);
+
+ // ...
+
+ void connect_handler(
+ const asio::error_code& ec,
+ std::vector<tcp::endpoint>::iterator i)
+ {
+ // ...
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_connect (4 of 6 overloads)]
+
+
+Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.RangeConnectHandler RangeConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ RangeConnectHandler && handler,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, an iterator denoting the successfully
+ // connected endpoint. Otherwise, the end iterator.
+ Iterator iterator
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+
+ // ...
+
+ r.async_resolve(q, resolve_handler);
+
+ // ...
+
+ void resolve_handler(
+ const asio::error_code& ec,
+ tcp::resolver::results_type results)
+ {
+ if (!ec)
+ {
+ asio::async_connect(s, results,
+ my_connect_condition(),
+ connect_handler);
+ }
+ }
+
+ // ...
+
+ void connect_handler(
+ const asio::error_code& ec,
+ const tcp::endpoint& endpoint)
+ {
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ std::cout << "Connected to: " << endpoint << std::endl;
+ }
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 async_connect (5 of 6 overloads)]
+
+
+(Deprecated.) Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ IteratorConnectHandler && handler,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, an iterator denoting the successfully
+ // connected endpoint. Otherwise, the end iterator.
+ Iterator iterator
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 async_connect (6 of 6 overloads)]
+
+
+Asynchronously establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``,
+ typename ``[link asio.reference.IteratorConnectHandler IteratorConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition,
+ IteratorConnectHandler && handler);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `async_connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[handler][The handler to be called when the connect operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation. if the sequence is empty, set to
+ // asio::error::not_found. Otherwise, contains the
+ // error from the last connection attempt.
+ const asio::error_code& error,
+
+ // On success, an iterator denoting the successfully
+ // connected endpoint. Otherwise, the end iterator.
+ Iterator iterator
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+
+ // ...
+
+ r.async_resolve(q, resolve_handler);
+
+ // ...
+
+ void resolve_handler(
+ const asio::error_code& ec,
+ tcp::resolver::iterator i)
+ {
+ if (!ec)
+ {
+ tcp::resolver::iterator end;
+ asio::async_connect(s, i, end,
+ my_connect_condition(),
+ connect_handler);
+ }
+ }
+
+ // ...
+
+ void connect_handler(
+ const asio::error_code& ec,
+ tcp::resolver::iterator i)
+ {
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ std::cout << "Connected to: " << i->endpoint() << std::endl;
+ }
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_read async_read]
+
+[indexterm1 asio.indexterm.async_read..async_read]
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload1 async_read]``(
+ AsyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload2 async_read]``(
+ AsyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload3 async_read]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ ReadHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload4 async_read]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload5 async_read]``(
+ AsyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read.overload6 async_read]``(
+ AsyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read.overload6 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_read (1 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream. 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.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_read(s, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::async_read(
+ s, buffers,
+ asio::transfer_all(),
+ handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_read (2 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream. 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.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's async\_read\_some function.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_read(s,
+ asio::buffer(data, size),
+ asio::transfer_at_least(32),
+ handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_read (3 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ ReadHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The specified dynamic buffer sequence is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::async_read(
+ s, buffers,
+ asio::transfer_all(),
+ handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_read (4 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The specified dynamic buffer sequence is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's async\_read\_some function.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 async_read (5 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::async_read(
+ s, b,
+ asio::transfer_all(),
+ handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 async_read (6 of 6 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data from a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read(
+ AsyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's async\_read\_some function.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes copied into the
+ // buffers. If an error occurred,
+ // this will be the number of
+ // bytes successfully transferred
+ // prior to the error.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_read_at async_read_at]
+
+[indexterm1 asio.indexterm.async_read_at..async_read_at]
+Start an asynchronous operation to read a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_at.overload1 async_read_at]``(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_at.overload2 async_read_at]``(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_at.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_at.overload3 async_read_at]``(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_at.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_at.overload4 async_read_at]``(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_at.overload4 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read_at.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_read_at (1 of 4 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_at(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a random access device at the specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's async\_read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the AsyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device. 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.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes copied into the buffers. If an error
+ // occurred, this will be the number of bytes successfully
+ // transferred prior to the error.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_read_at(d, 42, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::async_read_at(
+ d, 42, buffers,
+ asio::transfer_all(),
+ handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_read_at (2 of 4 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_at(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a random access device at the specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the AsyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device. 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.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's async\_read\_some\_at function.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes copied into the buffers. If an error
+ // occurred, this will be the number of bytes successfully
+ // transferred prior to the error.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_read_at(d, 42,
+ asio::buffer(data, size),
+ asio::transfer_at_least(32),
+ handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_read_at (3 of 4 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_at(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a random access device at the specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's async\_read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the AsyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes copied into the buffers. If an error
+ // occurred, this will be the number of bytes successfully
+ // transferred prior to the error.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::async_read_at(
+ d, 42, b,
+ asio::transfer_all(),
+ handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_read_at (4 of 4 overloads)]
+
+
+Start an asynchronous operation to read a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessReadDevice AsyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_at(
+ AsyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read a certain number of bytes of data from a random access device at the specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's async\_read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the AsyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's async\_read\_some\_at function.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes copied into the buffers. If an error
+ // occurred, this will be the number of bytes successfully
+ // transferred prior to the error.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_read_until async_read_until]
+
+[indexterm1 asio.indexterm.async_read_until..async_read_until]
+Start an asynchronous operation to read data into a dynamic buffer sequence, or into a streambuf, until it contains a delimiter, matches a regular expression, or a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload1 async_read_until]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload2 async_read_until]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload3 async_read_until]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload4 async_read_until]``(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ ReadHandler && handler,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload5 async_read_until]``(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload6 async_read_until]``(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload7 async_read_until]``(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_read_until.overload8 async_read_until]``(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ ReadHandler && handler,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_read_until.overload8 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read_until.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_read_until (1 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the dynamic buffer sequence's get area already contains the delimiter, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[delim][The delimiter character.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the dynamic buffer sequence's
+ // get area up to and including the delimiter.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a `std::string` until a newline is encountered:
+
+ std::string data;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, data, '\n', handler);
+
+
+After the `async_read_until` operation completes successfully, the buffer `data` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the buffer `data` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_read_until (2 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the dynamic buffer sequence's get area already contains the delimiter, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[delim][The delimiter string.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the dynamic buffer sequence's
+ // get area up to and including the delimiter.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a `std::string` until a CR-LF sequence is encountered:
+
+ std::string data;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, data, "\r\n", handler);
+
+
+After the `async_read_until` operation completes successfully, the string `data` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the string `data` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_read_until (3 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a dynamic buffer sequence until some part of its data matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains some data that matches a regular expression. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* A substring of the dynamic buffer sequence's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the dynamic buffer sequence's get area already contains data that matches the regular expression, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[expr][The regular expression.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the dynamic buffer
+ // sequence's get area up to and including the
+ // substring that matches the regular expression.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the dynamic buffer sequence for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a `std::string` until a CR-LF sequence is encountered:
+
+ std::string data;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, data,
+ boost::regex("\r\n"), handler);
+
+
+After the `async_read_until` operation completes successfully, the string `data` contains the data which matched the regular expression:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the match, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the string `data` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_read_until (4 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a dynamic buffer sequence until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ ReadHandler && handler,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to asynchronously read data into the specified dynamic buffer sequence until a user-defined match condition function object, when applied to the data contained in the dynamic buffer sequence, indicates a successful match. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the match condition function object already indicates a match, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<typename DynamicBuffer::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the dynamic buffer sequence's
+ // get area that have been fully consumed by the match
+ // function. O if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the function object. An application will typically leave that data in the dynamic buffer sequence for a subsequent async\_read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+[heading Examples]
+
+To asynchronously read data into a `std::string` until whitespace is encountered:
+
+ typedef asio::buffers_iterator<
+ asio::const_buffers_1> iterator;
+
+ std::pair<iterator, bool>
+ match_whitespace(iterator begin, iterator end)
+ {
+ iterator i = begin;
+ while (i != end)
+ if (std::isspace(*i++))
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+ ...
+ void handler(const asio::error_code& e, std::size_t size);
+ ...
+ std::string data;
+ asio::async_read_until(s, data, match_whitespace, handler);
+
+
+
+
+To asynchronously read data into a `std::string` until a matching character is found:
+
+ class match_char
+ {
+ public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+ private:
+ char c_;
+ };
+
+ namespace asio {
+ template <> struct is_match_condition<match_char>
+ : public boost::true_type {};
+ } // namespace asio
+ ...
+ void handler(const asio::error_code& e, std::size_t size);
+ ...
+ std::string data;
+ asio::async_read_until(s, data, match_char('a'), handler);
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 async_read_until (5 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the streambuf's get area already contains the delimiter, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[delim][The delimiter character.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the streambuf's get
+ // area up to and including the delimiter.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a streambuf until a newline is encountered:
+
+ asio::streambuf b;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, b, '\n', handler);
+
+
+After the `async_read_until` operation completes successfully, the buffer `b` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 async_read_until (6 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the streambuf's get area already contains the delimiter, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[delim][The delimiter string.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the streambuf's get
+ // area up to and including the delimiter.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a streambuf until a newline is encountered:
+
+ asio::streambuf b;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, b, "\r\n", handler);
+
+
+After the `async_read_until` operation completes successfully, the buffer `b` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 async_read_until (7 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a streambuf until some part of its data matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data into the specified streambuf until the streambuf's get area contains some data that matches a regular expression. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* A substring of the streambuf's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the streambuf's get area already contains data that matches the regular expression, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[expr][The regular expression.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the streambuf's get
+ // area up to and including the substring
+ // that matches the regular. expression.
+ // 0 if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the streambuf may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the streambuf for a subsequent async\_read\_until operation to examine.
+
+
+[heading Example]
+
+To asynchronously read data into a streambuf until a CR-LF sequence is encountered:
+
+ asio::streambuf b;
+ ...
+ void handler(const asio::error_code& e, std::size_t size)
+ {
+ if (!e)
+ {
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+ ...
+ }
+ }
+ ...
+ asio::async_read_until(s, b, boost::regex("\r\n"), handler);
+
+
+After the `async_read_until` operation completes successfully, the buffer `b` contains the data which matched the regular expression:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the match, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `async_read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 async_read_until (8 of 8 overloads)]
+
+
+Start an asynchronous operation to read data into a streambuf until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.AsyncReadStream AsyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_until(
+ AsyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ ReadHandler && handler,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to asynchronously read data into the specified streambuf until a user-defined match condition function object, when applied to the data contained in the streambuf, indicates a successful match. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a ['composed operation]. If the match condition function object already indicates a match, this asynchronous operation completes immediately. The program must ensure that the stream performs no other read operations (such as async\_read, async\_read\_until, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the AsyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // The number of bytes in the streambuf's get
+ // area that have been fully consumed by the
+ // match function. O if an error occurred.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful async\_read\_until operation, the streambuf may contain additional data beyond that which matched the function object. An application will typically leave that data in the streambuf for a subsequent async\_read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+[heading Examples]
+
+To asynchronously read data into a streambuf until whitespace is encountered:
+
+ typedef asio::buffers_iterator<
+ asio::streambuf::const_buffers_type> iterator;
+
+ std::pair<iterator, bool>
+ match_whitespace(iterator begin, iterator end)
+ {
+ iterator i = begin;
+ while (i != end)
+ if (std::isspace(*i++))
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+ ...
+ void handler(const asio::error_code& e, std::size_t size);
+ ...
+ asio::streambuf b;
+ asio::async_read_until(s, b, match_whitespace, handler);
+
+
+
+
+To asynchronously read data into a streambuf until a matching character is found:
+
+ class match_char
+ {
+ public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+ private:
+ char c_;
+ };
+
+ namespace asio {
+ template <> struct is_match_condition<match_char>
+ : public boost::true_type {};
+ } // namespace asio
+ ...
+ void handler(const asio::error_code& e, std::size_t size);
+ ...
+ asio::streambuf b;
+ asio::async_read_until(s, b, match_char('a'), handler);
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_result async_result]
+
+
+An interface for customising the behaviour of an initiating function.
+
+
+ template<
+ typename CompletionToken,
+ typename Signature>
+ class async_result
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.async_result.completion_handler_type [*completion_handler_type]]]
+ [The concrete completion handler type for the specific signature. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.async_result.return_type [*return_type]]]
+ [The return type of the initiating function. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_result.async_result [*async_result]]]
+ [Construct an async result from a given handler. ]
+ ]
+
+ [
+ [[link asio.reference.async_result.get [*get]]]
+ [Obtain the value to be returned from the initiating function. ]
+ ]
+
+]
+
+The [link asio.reference.async_result `async_result`] traits class is used for determining:
+
+
+* the concrete completion handler type to be called at the end of the asynchronous operation;
+
+
+* the initiating function return type; and
+
+
+* 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.
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_result async_result::async_result]
+
+[indexterm2 asio.indexterm.async_result.async_result..async_result..async_result]
+Construct an async result from a given handler.
+
+
+ async_result(
+ completion_handler_type & h);
+
+
+When using a specalised [link asio.reference.async_result `async_result`], the constructor has an opportunity to initialise some state associated with the completion handler, which is then returned from the initiating function.
+
+
+[endsect]
+
+
+
+[section:completion_handler_type async_result::completion_handler_type]
+
+[indexterm2 asio.indexterm.async_result.completion_handler_type..completion_handler_type..async_result]
+The concrete completion handler type for the specific signature.
+
+
+ typedef CompletionToken completion_handler_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get async_result::get]
+
+[indexterm2 asio.indexterm.async_result.get..get..async_result]
+Obtain the value to be returned from the initiating function.
+
+
+ return_type get();
+
+
+
+[endsect]
+
+
+
+[section:return_type async_result::return_type]
+
+[indexterm2 asio.indexterm.async_result.return_type..return_type..async_result]
+The return type of the initiating function.
+
+
+ typedef void return_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:async_result_lt__Handler__gt_ async_result< Handler >]
+
+
+(Deprecated: Use two-parameter version of [link asio.reference.async_result `async_result`].) An interface for customising the behaviour of an initiating function.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ class async_result< Handler >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.async_result_lt__Handler__gt_.type [*type]]]
+ [The return type of the initiating function. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_result_lt__Handler__gt_.async_result [*async_result]]]
+ [Construct an async result from a given handler. ]
+ ]
+
+ [
+ [[link asio.reference.async_result_lt__Handler__gt_.get [*get]]]
+ [Obtain the value to be returned from the initiating function. ]
+ ]
+
+]
+
+This template may be specialised for user-defined handler types.
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_result async_result< Handler >::async_result]
+
+[indexterm2 asio.indexterm.async_result_lt__Handler__gt_.async_result..async_result..async_result< Handler >]
+Construct an async result from a given handler.
+
+
+ async_result(
+ Handler & );
+
+
+When using a specalised [link asio.reference.async_result `async_result`], the constructor has an opportunity to initialise some state associated with the handler, which is then returned from the initiating function.
+
+
+[endsect]
+
+
+
+[section:get async_result< Handler >::get]
+
+[indexterm2 asio.indexterm.async_result_lt__Handler__gt_.get..get..async_result< Handler >]
+Obtain the value to be returned from the initiating function.
+
+
+ type get();
+
+
+
+[endsect]
+
+
+
+[section:type async_result< Handler >::type]
+
+[indexterm2 asio.indexterm.async_result_lt__Handler__gt_.type..type..async_result< Handler >]
+The return type of the initiating function.
+
+
+ typedef void type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/async_result.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_ async_result< std::packaged_task< Result(Args...)>, Signature >]
+
+
+Partial specialisation of `async_result` for `std::packaged_task`.
+
+
+ template<
+ typename Result,
+ typename... Args,
+ typename Signature>
+ class async_result< std::packaged_task< Result(Args...)>, Signature >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.completion_handler_type [*completion_handler_type]]]
+ [The packaged task is the concrete completion handler type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.return_type [*return_type]]]
+ [The return type of the initiating function is the future obtained from the packaged task. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.async_result [*async_result]]]
+ [The constructor extracts the future from the packaged task. ]
+ ]
+
+ [
+ [[link asio.reference.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.get [*get]]]
+ [Returns the packaged task's future. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/packaged_task.hpp]
+
+['Convenience header: ]None
+
+
+[section:async_result async_result< std::packaged_task< Result(Args...)>, Signature >::async_result]
+
+[indexterm2 asio.indexterm.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.async_result..async_result..async_result< std::packaged_task< Result(Args\.\.\.)>, Signature >]
+The constructor extracts the future from the packaged task.
+
+
+ async_result(
+ completion_handler_type & h);
+
+
+
+[endsect]
+
+
+
+[section:completion_handler_type async_result< std::packaged_task< Result(Args...)>, Signature >::completion_handler_type]
+
+[indexterm2 asio.indexterm.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.completion_handler_type..completion_handler_type..async_result< std::packaged_task< Result(Args\.\.\.)>, Signature >]
+The packaged task is the concrete completion handler type.
+
+
+ typedef std::packaged_task< Result(Args...)> completion_handler_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/packaged_task.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+
+[section:get async_result< std::packaged_task< Result(Args...)>, Signature >::get]
+
+[indexterm2 asio.indexterm.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.get..get..async_result< std::packaged_task< Result(Args\.\.\.)>, Signature >]
+Returns the packaged task's future.
+
+
+ return_type get();
+
+
+
+[endsect]
+
+
+
+[section:return_type async_result< std::packaged_task< Result(Args...)>, Signature >::return_type]
+
+[indexterm2 asio.indexterm.async_result_lt__std__packaged_task_lt__Result_lp_Args_ellipsis__rp__gt__comma__Signature__gt_.return_type..return_type..async_result< std::packaged_task< Result(Args\.\.\.)>, Signature >]
+The return type of the initiating function is the future obtained from the packaged task.
+
+
+ typedef std::future< Result > return_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/packaged_task.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:async_write async_write]
+
+[indexterm1 asio.indexterm.async_write..async_write]
+Start an asynchronous operation to write a certain amount of data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload1 async_write]``(
+ AsyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload2 async_write]``(
+ AsyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload3 async_write]``(
+ AsyncWriteStream & s,
+ DynamicBuffer && buffers,
+ WriteHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload4 async_write]``(
+ AsyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload5 async_write]``(
+ AsyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write.overload6 async_write]``(
+ AsyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write.overload6 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/write.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_write (1 of 6 overloads)]
+
+
+Start an asynchronous operation to write all of the supplied data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_write(s, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_write (2 of 6 overloads)]
+
+
+Start an asynchronous operation to write a certain amount of data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. 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.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's async\_write\_some function.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_write(s,
+ asio::buffer(data, size),
+ asio::transfer_at_least(32),
+ handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_write (3 of 6 overloads)]
+
+
+Start an asynchronous operation to write all of the supplied data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ DynamicBuffer && buffers,
+ WriteHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. 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. Successfully written data is automatically consumed from the buffers.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_write (4 of 6 overloads)]
+
+
+Start an asynchronous operation to write a certain amount of data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. 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. Successfully written data is automatically consumed from the buffers.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's async\_write\_some function.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 async_write (5 of 6 overloads)]
+
+
+Start an asynchronous operation to write all of the supplied data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 async_write (6 of 6 overloads)]
+
+
+Start an asynchronous operation to write a certain amount of data to a stream.
+
+
+ template<
+ typename ``[link asio.reference.AsyncWriteStream AsyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write(
+ AsyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a ['composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the AsyncWriteStream concept.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's async\_write\_some function.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+
+ std::size_t bytes_transferred // Number of bytes written from the
+ // buffers. If an error occurred,
+ // this will be less than the sum
+ // of the buffer sizes.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_write_at async_write_at]
+
+[indexterm1 asio.indexterm.async_write_at..async_write_at]
+Start an asynchronous operation to write a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write_at.overload1 async_write_at]``(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write_at.overload2 async_write_at]``(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write_at.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write_at.overload3 async_write_at]``(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write_at.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.async_write_at.overload4 async_write_at]``(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.async_write_at.overload4 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/write_at.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 async_write_at (1 of 4 overloads)]
+
+
+Start an asynchronous operation to write all of the supplied data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_at(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function, and is known as a ['composed operation]. The program must ensure that the device performs no ['overlapping] write operations (such as async\_write\_at, the device's async\_write\_some\_at function, or any other composed operations that perform writes) until this operation completes. Operations are overlapping if the regions defined by their offsets, and the numbers of bytes to write, intersect.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the AsyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes written from the buffers. If an error
+ // occurred, this will be less than the sum of the buffer sizes.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_write_at(d, 42, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 async_write_at (2 of 4 overloads)]
+
+
+Start an asynchronous operation to write a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_at(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function, and is known as a ['composed operation]. The program must ensure that the device performs no ['overlapping] write operations (such as async\_write\_at, the device's async\_write\_some\_at function, or any other composed operations that perform writes) until this operation completes. Operations are overlapping if the regions defined by their offsets, and the numbers of bytes to write, intersect.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the AsyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. 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.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's async\_write\_some\_at function.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes written from the buffers. If an error
+ // occurred, this will be less than the sum of the buffer sizes.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::async_write_at(d, 42,
+ asio::buffer(data, size),
+ asio::transfer_at_least(32),
+ handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 async_write_at (3 of 4 overloads)]
+
+
+Start an asynchronous operation to write all of the supplied data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_at(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function, and is known as a ['composed operation]. The program must ensure that the device performs no ['overlapping] write operations (such as async\_write\_at, the device's async\_write\_some\_at function, or any other composed operations that perform writes) until this operation completes. Operations are overlapping if the regions defined by their offsets, and the numbers of bytes to write, intersect.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the AsyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes written from the buffers. If an error
+ // occurred, this will be less than the sum of the buffer sizes.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 async_write_at (4 of 4 overloads)]
+
+
+Start an asynchronous operation to write a certain amount of data at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.AsyncRandomAccessWriteDevice AsyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_at(
+ AsyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function, and is known as a ['composed operation]. The program must ensure that the device performs no ['overlapping] write operations (such as async\_write\_at, the device's async\_write\_some\_at function, or any other composed operations that perform writes) until this operation completes. Operations are overlapping if the regions defined by their offsets, and the numbers of bytes to write, intersect.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the AsyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][A [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written. Ownership of the streambuf is retained by the caller, which must guarantee that it remains valid until the handler is called.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest async_write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's async\_write\_some\_at function.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ // Result of operation.
+ const asio::error_code& error,
+
+ // Number of bytes written from the buffers. If an error
+ // occurred, this will be less than the sum of the buffer sizes.
+ std::size_t bytes_transferred
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bad_executor bad_executor]
+
+
+Exception thrown when trying to access an empty polymorphic executor.
+
+
+ class bad_executor :
+ public std::exception
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.bad_executor.bad_executor [*bad_executor]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.bad_executor.what [*what]]]
+ [Obtain message associated with exception. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:bad_executor bad_executor::bad_executor]
+
+[indexterm2 asio.indexterm.bad_executor.bad_executor..bad_executor..bad_executor]
+Constructor.
+
+
+ bad_executor();
+
+
+
+[endsect]
+
+
+
+[section:what bad_executor::what]
+
+[indexterm2 asio.indexterm.bad_executor.what..what..bad_executor]
+Obtain message associated with exception.
+
+
+ virtual const char * what() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_datagram_socket basic_datagram_socket]
+
+
+Provides datagram-oriented socket functionality.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_datagram_socket :
+ public basic_socket< Protocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.basic_datagram_socket [*basic_datagram_socket]]]
+ [Construct a basic_datagram_socket without opening it.
+
+ Construct and open a basic_datagram_socket.
+
+ Construct a basic_datagram_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_datagram_socket on an existing native socket.
+
+ Move-construct a basic_datagram_socket from another.
+
+ Move-construct a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_datagram_socket from another.
+
+ Move-assign a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive_from [*receive_from]]]
+ [Receive a datagram with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send_to [*send_to]]]
+ [Send a datagram to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket._basic_datagram_socket [*~basic_datagram_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_datagram_socket `basic_datagram_socket`] class template provides asynchronous and blocking datagram-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign basic_datagram_socket::assign]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.assign..assign..basic_datagram_socket]
+Assign an existing native socket to the socket.
+
+
+ void ``[link asio.reference.basic_datagram_socket.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.assign.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::assign (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::assign (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_connect basic_datagram_socket::async_connect]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_connect..async_connect..basic_datagram_socket]
+Start an asynchronous connect.
+
+
+ template<
+ typename ``[link asio.reference.ConnectHandler ConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ const endpoint_type & peer_endpoint,
+ ConnectHandler && handler);
+
+
+This function is used to asynchronously connect a socket to the specified remote endpoint. The function call always returns immediately.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected. Copies will be made of the endpoint object as required.]]
+
+[[handler][The handler to be called when the connection operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void connect_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Connect succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.async_connect(endpoint, connect_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:async_receive basic_datagram_socket::async_receive]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_receive..async_receive..basic_datagram_socket]
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_receive.overload1 async_receive]``(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_receive.overload2 async_receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_receive.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::async_receive (1 of 2 overloads)]
+
+
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the datagram socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::async_receive (2 of 2 overloads)]
+
+
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the datagram socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_receive_from basic_datagram_socket::async_receive_from]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_receive_from..async_receive_from..basic_datagram_socket]
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_receive_from.overload1 async_receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_receive_from.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_receive_from.overload2 async_receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_receive_from.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::async_receive_from (1 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive a datagram. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive_from(
+ asio::buffer(data, size), sender_endpoint, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::async_receive_from (2 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive a datagram. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_send basic_datagram_socket::async_send]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_send..async_send..basic_datagram_socket]
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_send.overload1 async_send]``(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_send.overload2 async_send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_send.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::async_send (1 of 2 overloads)]
+
+
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send data on the datagram socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_send(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::async_send (2 of 2 overloads)]
+
+
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send data on the datagram socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_send_to basic_datagram_socket::async_send_to]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_send_to..async_send_to..basic_datagram_socket]
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_send_to.overload1 async_send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_send_to.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_datagram_socket.async_send_to.overload2 async_send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.async_send_to.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::async_send_to (1 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send a datagram to the specified remote endpoint. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[destination][The remote endpoint to which the data will be sent. Copies will be made of the endpoint as required.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ 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);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::async_send_to (2 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send a datagram to the specified remote endpoint. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[destination][The remote endpoint to which the data will be sent. Copies will be made of the endpoint as required.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait basic_datagram_socket::async_wait]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.async_wait..async_wait..basic_datagram_socket]
+Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:at_mark basic_datagram_socket::at_mark]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.at_mark..at_mark..basic_datagram_socket]
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool ``[link asio.reference.basic_datagram_socket.at_mark.overload1 at_mark]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.at_mark.overload1 more...]]``
+
+ bool ``[link asio.reference.basic_datagram_socket.at_mark.overload2 at_mark]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.at_mark.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::at_mark (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark() const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::at_mark (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark(
+ asio::error_code & ec) const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:available basic_datagram_socket::available]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.available..available..basic_datagram_socket]
+Determine the number of bytes available for reading.
+
+
+ std::size_t ``[link asio.reference.basic_datagram_socket.available.overload1 available]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.available.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_datagram_socket.available.overload2 available]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.available.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::available (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available() const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::available (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available(
+ asio::error_code & ec) const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_datagram_socket basic_datagram_socket::basic_datagram_socket]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.basic_datagram_socket..basic_datagram_socket..basic_datagram_socket]
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] without opening it.
+
+
+ explicit ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload1 basic_datagram_socket]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.basic_datagram_socket `basic_datagram_socket`].
+
+
+ ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload2 basic_datagram_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload2 more...]]``
+
+
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`], opening it and binding it to the given local endpoint.
+
+
+ ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload3 basic_datagram_socket]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] on an existing native socket.
+
+
+ ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload4 basic_datagram_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from another.
+
+
+ ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload5 basic_datagram_socket]``(
+ basic_datagram_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_datagram_socket.basic_datagram_socket.overload6 basic_datagram_socket]``(
+ basic_datagram_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.basic_datagram_socket.overload6 more...]]``
+
+
+[section:overload1 basic_datagram_socket::basic_datagram_socket (1 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] without opening it.
+
+
+ basic_datagram_socket(
+ asio::io_context & io_context);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the datagram socket will use to dispatch handlers for any asynchronous operations performed on the socket. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::basic_datagram_socket (2 of 6 overloads)]
+
+
+Construct and open a [link asio.reference.basic_datagram_socket `basic_datagram_socket`].
+
+
+ basic_datagram_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates and opens a datagram socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the datagram socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::basic_datagram_socket (3 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`], opening it and binding it to the given local endpoint.
+
+
+ basic_datagram_socket(
+ asio::io_context & io_context,
+ const endpoint_type & 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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the datagram socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[endpoint][An endpoint on the local machine to which the datagram socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_datagram_socket::basic_datagram_socket (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] on an existing native socket.
+
+
+ basic_datagram_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+This constructor creates a datagram socket object to hold an existing native socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the datagram socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_socket][The new underlying socket implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_datagram_socket::basic_datagram_socket (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from another.
+
+
+ basic_datagram_socket(
+ basic_datagram_socket && other);
+
+
+This constructor moves a datagram socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_datagram_socket `basic_datagram_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_datagram_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_datagram_socket::basic_datagram_socket (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_datagram_socket(
+ basic_datagram_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves a datagram socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_datagram_socket `basic_datagram_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_datagram_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_datagram_socket::bind]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.bind..bind..basic_datagram_socket]
+Bind the socket to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_datagram_socket.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.bind.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::bind (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::bind (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ asio::error_code ec;
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_datagram_socket::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.broadcast..broadcast..basic_datagram_socket]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_datagram_socket::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.bytes_readable..bytes_readable..basic_datagram_socket]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_datagram_socket::cancel]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.cancel..cancel..basic_datagram_socket]
+Cancel all asynchronous operations associated with the socket.
+
+
+ void ``[link asio.reference.basic_datagram_socket.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::cancel (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::cancel (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_datagram_socket::close]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.close..close..basic_datagram_socket]
+Close the socket.
+
+
+ void ``[link asio.reference.basic_datagram_socket.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.close.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::close (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close();
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::close (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:connect basic_datagram_socket::connect]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.connect..connect..basic_datagram_socket]
+Connect the socket to the specified endpoint.
+
+
+ void ``[link asio.reference.basic_datagram_socket.connect.overload1 connect]``(
+ const endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.connect.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.connect.overload2 connect]``(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.connect.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::connect (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.connect(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::connect (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ asio::error_code ec;
+ socket.connect(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_datagram_socket::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.debug..debug..basic_datagram_socket]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_datagram_socket::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.do_not_route..do_not_route..basic_datagram_socket]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_datagram_socket::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.enable_connection_aborted..enable_connection_aborted..basic_datagram_socket]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_datagram_socket::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.endpoint_type..endpoint_type..basic_datagram_socket]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_datagram_socket::executor_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.executor_type..executor_type..basic_datagram_socket]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_datagram_socket::get_executor]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.get_executor..get_executor..basic_datagram_socket]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_datagram_socket::get_io_context]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.get_io_context..get_io_context..basic_datagram_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_datagram_socket::get_io_service]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.get_io_service..get_io_service..basic_datagram_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_datagram_socket::get_option]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.get_option..get_option..basic_datagram_socket]
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_datagram_socket.get_option.overload1 get_option]``(
+ GettableSocketOption & option) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_datagram_socket.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::get_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::get_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ asio::error_code ec;
+ socket.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_datagram_socket::io_control]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.io_control..io_control..basic_datagram_socket]
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_datagram_socket.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_datagram_socket.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::io_control (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::io_control (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_datagram_socket::is_open]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.is_open..is_open..basic_datagram_socket]
+Determine whether the socket is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_datagram_socket::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.keep_alive..keep_alive..basic_datagram_socket]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_datagram_socket::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.linger..linger..basic_datagram_socket]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:local_endpoint basic_datagram_socket::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.local_endpoint..local_endpoint..basic_datagram_socket]
+Get the local endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_datagram_socket.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_datagram_socket.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::local_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::local_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer basic_datagram_socket::lowest_layer]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.lowest_layer..lowest_layer..basic_datagram_socket]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.basic_datagram_socket.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.basic_datagram_socket.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type basic_datagram_socket::lowest_layer_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.lowest_layer_type..lowest_layer_type..basic_datagram_socket]
+A [link asio.reference.basic_socket `basic_socket`] is always the lowest layer.
+
+
+ typedef basic_socket< Protocol > lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections basic_datagram_socket::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.max_connections..max_connections..basic_datagram_socket]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_datagram_socket::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.max_listen_connections..max_listen_connections..basic_datagram_socket]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_datagram_socket::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.message_do_not_route..message_do_not_route..basic_datagram_socket]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_datagram_socket::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.message_end_of_record..message_end_of_record..basic_datagram_socket]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_datagram_socket::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.message_flags..message_flags..basic_datagram_socket]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_datagram_socket::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.message_out_of_band..message_out_of_band..basic_datagram_socket]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_datagram_socket::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.message_peek..message_peek..basic_datagram_socket]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_datagram_socket::native_handle]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.native_handle..native_handle..basic_datagram_socket]
+Get the native socket representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the socket. This is intended to allow access to native socket functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_datagram_socket::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.native_handle_type..native_handle_type..basic_datagram_socket]
+The native representation of a socket.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_datagram_socket::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.native_non_blocking..native_non_blocking..basic_datagram_socket]
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool ``[link asio.reference.basic_datagram_socket.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void ``[link asio.reference.basic_datagram_socket.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::native_non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native socket. This mode has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying socket is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the socket object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native socket.
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::native_non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::native_non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_datagram_socket::non_blocking]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.non_blocking..non_blocking..basic_datagram_socket]
+Gets the non-blocking mode of the socket.
+
+
+ bool ``[link asio.reference.basic_datagram_socket.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void ``[link asio.reference.basic_datagram_socket.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the socket.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_datagram_socket::open]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.open..open..basic_datagram_socket]
+Open the socket using the specified protocol.
+
+
+ void ``[link asio.reference.basic_datagram_socket.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.open.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::open (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::open (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ socket.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_datagram_socket::operator=]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.operator_eq_..operator=..basic_datagram_socket]
+Move-assign a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from another.
+
+
+ basic_datagram_socket & ``[link asio.reference.basic_datagram_socket.operator_eq_.overload1 operator=]``(
+ basic_datagram_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_datagram_socket >::type & ``[link asio.reference.basic_datagram_socket.operator_eq_.overload2 operator=]``(
+ basic_datagram_socket< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from another.
+
+
+ basic_datagram_socket & operator=(
+ basic_datagram_socket && other);
+
+
+This assignment operator moves a datagram socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_datagram_socket `basic_datagram_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_datagram_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_datagram_socket `basic_datagram_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_datagram_socket >::type & operator=(
+ basic_datagram_socket< Protocol1 > && other);
+
+
+This assignment operator moves a datagram socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_datagram_socket `basic_datagram_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_datagram_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_datagram_socket::protocol_type]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.protocol_type..protocol_type..basic_datagram_socket]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:receive basic_datagram_socket::receive]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.receive..receive..basic_datagram_socket]
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive.overload1 receive]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive.overload2 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive.overload3 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::receive (1 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected datagram socket.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::receive (2 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected datagram socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::receive (3 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected datagram socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_buffer_size basic_datagram_socket::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.receive_buffer_size..receive_buffer_size..basic_datagram_socket]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:receive_from basic_datagram_socket::receive_from]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.receive_from..receive_from..basic_datagram_socket]
+Receive a datagram with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive_from.overload1 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive_from.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive_from.overload2 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive_from.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.receive_from.overload3 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.receive_from.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::receive_from (1 of 3 overloads)]
+
+
+Receive a datagram with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint);
+
+
+This function is used to receive a datagram. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the datagram.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::ip::udp::endpoint sender_endpoint;
+ socket.receive_from(
+ asio::buffer(data, size), sender_endpoint);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::receive_from (2 of 3 overloads)]
+
+
+Receive a datagram with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags);
+
+
+This function is used to receive a datagram. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the datagram.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::receive_from (3 of 3 overloads)]
+
+
+Receive a datagram with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+This function is used to receive a datagram. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the datagram.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_low_watermark basic_datagram_socket::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.receive_low_watermark..receive_low_watermark..basic_datagram_socket]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:remote_endpoint basic_datagram_socket::remote_endpoint]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.remote_endpoint..remote_endpoint..basic_datagram_socket]
+Get the remote endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_datagram_socket.remote_endpoint.overload1 remote_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.remote_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_datagram_socket.remote_endpoint.overload2 remote_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.remote_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::remote_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint() const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::remote_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:reuse_address basic_datagram_socket::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.reuse_address..reuse_address..basic_datagram_socket]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send basic_datagram_socket::send]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.send..send..basic_datagram_socket]
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send.overload1 send]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send.overload2 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send.overload3 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::send (1 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One ore more data buffers to be sent on the socket.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected datagram socket.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.send(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::send (2 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One ore more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected datagram socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::send (3 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected datagram socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:send_buffer_size basic_datagram_socket::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.send_buffer_size..send_buffer_size..basic_datagram_socket]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_datagram_socket::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.send_low_watermark..send_low_watermark..basic_datagram_socket]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_datagram_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send_to basic_datagram_socket::send_to]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.send_to..send_to..basic_datagram_socket]
+Send a datagram to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send_to.overload1 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send_to.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send_to.overload2 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send_to.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_datagram_socket.send_to.overload3 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.send_to.overload3 more...]]``
+
+
+[section:overload1 basic_datagram_socket::send_to (1 of 3 overloads)]
+
+
+Send a datagram to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::ip::udp::endpoint destination(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.send_to(asio::buffer(data, size), destination);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::send_to (2 of 3 overloads)]
+
+
+Send a datagram to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_datagram_socket::send_to (3 of 3 overloads)]
+
+
+Send a datagram to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_option basic_datagram_socket::set_option]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.set_option..set_option..basic_datagram_socket]
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_datagram_socket.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_datagram_socket.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::set_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::set_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ asio::error_code ec;
+ socket.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown basic_datagram_socket::shutdown]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.shutdown..shutdown..basic_datagram_socket]
+Disable sends or receives on the socket.
+
+
+ void ``[link asio.reference.basic_datagram_socket.shutdown.overload1 shutdown]``(
+ shutdown_type what);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.shutdown.overload2 shutdown]``(
+ shutdown_type what,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.shutdown.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::shutdown (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::shutdown (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what,
+ asio::error_code & ec);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_datagram_socket::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.shutdown_type..shutdown_type..basic_datagram_socket]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_datagram_socket.shutdown_type.shutdown_receive..shutdown_receive..basic_datagram_socket]
+[indexterm2 asio.indexterm.basic_datagram_socket.shutdown_type.shutdown_send..shutdown_send..basic_datagram_socket]
+[indexterm2 asio.indexterm.basic_datagram_socket.shutdown_type.shutdown_both..shutdown_both..basic_datagram_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_datagram_socket::wait]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.wait..wait..basic_datagram_socket]
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_datagram_socket.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_datagram_socket.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_datagram_socket.wait.overload2 more...]]``
+
+
+[section:overload1 basic_datagram_socket::wait (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.wait(asio::ip::tcp::socket::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_datagram_socket::wait (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.wait(asio::ip::tcp::socket::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_datagram_socket::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_datagram_socket.wait_type..wait_type..basic_datagram_socket]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_datagram_socket.wait_type.wait_read..wait_read..basic_datagram_socket]
+[indexterm2 asio.indexterm.basic_datagram_socket.wait_type.wait_write..wait_write..basic_datagram_socket]
+[indexterm2 asio.indexterm.basic_datagram_socket.wait_type.wait_error..wait_error..basic_datagram_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_basic_datagram_socket basic_datagram_socket::~basic_datagram_socket]
+
+[indexterm2 asio.indexterm.basic_datagram_socket._basic_datagram_socket..~basic_datagram_socket..basic_datagram_socket]
+Destroys the socket.
+
+
+ ~basic_datagram_socket();
+
+
+This function destroys the socket, cancelling any outstanding asynchronous operations associated with the socket as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_deadline_timer basic_deadline_timer]
+
+
+Provides waitable timer functionality.
+
+
+ template<
+ typename Time,
+ typename ``[link asio.reference.TimeTraits TimeTraits]`` = asio::time_traits<Time>>
+ class basic_deadline_timer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.duration_type [*duration_type]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.time_type [*time_type]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.traits_type [*traits_type]]]
+ [The time traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_deadline_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.basic_deadline_timer [*basic_deadline_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_deadline_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.expires_at [*expires_at]]]
+ [Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.expires_from_now [*expires_from_now]]]
+ [Get the timer's expiry time relative to now.
+
+ Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_deadline_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer._basic_deadline_timer [*~basic_deadline_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_deadline_timer `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 [link asio.reference.deadline_timer `deadline_timer`] typedef.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait:
+
+ // Construct a timer without setting an expiry time.
+ asio::deadline_timer timer(io_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();
+
+
+
+
+
+Performing an asynchronous wait:
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::deadline_timer timer(io_context,
+ boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading 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:
+
+
+
+ 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.
+ }
+ }
+
+
+
+
+
+* 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_wait basic_deadline_timer::async_wait]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.async_wait..async_wait..basic_deadline_timer]
+Start an asynchronous wait on the timer.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ WaitHandler && handler);
+
+
+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:
+
+
+* The timer has expired.
+
+
+* The timer was cancelled, in which case the handler is passed the error code `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:basic_deadline_timer basic_deadline_timer::basic_deadline_timer]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.basic_deadline_timer..basic_deadline_timer..basic_deadline_timer]
+Constructor.
+
+
+ explicit ``[link asio.reference.basic_deadline_timer.basic_deadline_timer.overload1 basic_deadline_timer]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.basic_deadline_timer.overload1 more...]]``
+
+
+Constructor to set a particular expiry time as an absolute time.
+
+
+ ``[link asio.reference.basic_deadline_timer.basic_deadline_timer.overload2 basic_deadline_timer]``(
+ asio::io_context & io_context,
+ const time_type & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.basic_deadline_timer.overload2 more...]]``
+
+
+Constructor to set a particular expiry time relative to now.
+
+
+ ``[link asio.reference.basic_deadline_timer.basic_deadline_timer.overload3 basic_deadline_timer]``(
+ asio::io_context & io_context,
+ const duration_type & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.basic_deadline_timer.overload3 more...]]``
+
+
+Move-construct a [link asio.reference.basic_deadline_timer `basic_deadline_timer`] from another.
+
+
+ ``[link asio.reference.basic_deadline_timer.basic_deadline_timer.overload4 basic_deadline_timer]``(
+ basic_deadline_timer && other);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.basic_deadline_timer.overload4 more...]]``
+
+
+[section:overload1 basic_deadline_timer::basic_deadline_timer (1 of 4 overloads)]
+
+
+Constructor.
+
+
+ basic_deadline_timer(
+ asio::io_context & io_context);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::basic_deadline_timer (2 of 4 overloads)]
+
+
+Constructor to set a particular expiry time as an absolute time.
+
+
+ basic_deadline_timer(
+ asio::io_context & io_context,
+ const time_type & expiry_time);
+
+
+This constructor creates a timer and sets the expiry time.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer.]]
+
+[[expiry_time][The expiry time to be used for the timer, expressed as an absolute time. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_deadline_timer::basic_deadline_timer (3 of 4 overloads)]
+
+
+Constructor to set a particular expiry time relative to now.
+
+
+ basic_deadline_timer(
+ asio::io_context & io_context,
+ const duration_type & expiry_time);
+
+
+This constructor creates a timer and sets the expiry time.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer.]]
+
+[[expiry_time][The expiry time to be used for the timer, relative to now. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_deadline_timer::basic_deadline_timer (4 of 4 overloads)]
+
+
+Move-construct a [link asio.reference.basic_deadline_timer `basic_deadline_timer`] from another.
+
+
+ basic_deadline_timer(
+ basic_deadline_timer && other);
+
+
+This constructor moves a timer from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_deadline_timer `basic_deadline_timer`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_deadline_timer(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:cancel basic_deadline_timer::cancel]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.cancel..cancel..basic_deadline_timer]
+Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.cancel.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_deadline_timer::cancel (1 of 2 overloads)]
+
+
+Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t cancel();
+
+
+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.
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::cancel (2 of 2 overloads)]
+
+
+Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t cancel(
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:cancel_one basic_deadline_timer::cancel_one]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.cancel_one..cancel_one..basic_deadline_timer]
+Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.cancel_one.overload1 cancel_one]``();
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.cancel_one.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.cancel_one.overload2 cancel_one]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.cancel_one.overload2 more...]]``
+
+
+[section:overload1 basic_deadline_timer::cancel_one (1 of 2 overloads)]
+
+
+Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t cancel_one();
+
+
+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.
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled. That is, either 0 or 1.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel_one()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::cancel_one (2 of 2 overloads)]
+
+
+Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t cancel_one(
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled. That is, either 0 or 1.
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel_one()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:duration_type basic_deadline_timer::duration_type]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.duration_type..duration_type..basic_deadline_timer]
+The duration type.
+
+
+ typedef traits_type::duration_type duration_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_deadline_timer::executor_type]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.executor_type..executor_type..basic_deadline_timer]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:expires_at basic_deadline_timer::expires_at]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.expires_at..expires_at..basic_deadline_timer]
+Get the timer's expiry time as an absolute time.
+
+
+ time_type ``[link asio.reference.basic_deadline_timer.expires_at.overload1 expires_at]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_at.overload1 more...]]``
+
+
+Set the timer's expiry time as an absolute time.
+
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.expires_at.overload2 expires_at]``(
+ const time_type & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_at.overload2 more...]]``
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.expires_at.overload3 expires_at]``(
+ const time_type & expiry_time,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_at.overload3 more...]]``
+
+
+[section:overload1 basic_deadline_timer::expires_at (1 of 3 overloads)]
+
+
+Get the timer's expiry time as an absolute time.
+
+
+ time_type expires_at() const;
+
+
+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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::expires_at (2 of 3 overloads)]
+
+
+Set the timer's expiry time as an absolute time.
+
+
+ std::size_t expires_at(
+ const time_type & expiry_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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_at()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload3 basic_deadline_timer::expires_at (3 of 3 overloads)]
+
+
+Set the timer's expiry time as an absolute time.
+
+
+ std::size_t expires_at(
+ const time_type & expiry_time,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_at()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:expires_from_now basic_deadline_timer::expires_from_now]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.expires_from_now..expires_from_now..basic_deadline_timer]
+Get the timer's expiry time relative to now.
+
+
+ duration_type ``[link asio.reference.basic_deadline_timer.expires_from_now.overload1 expires_from_now]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_from_now.overload1 more...]]``
+
+
+Set the timer's expiry time relative to now.
+
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.expires_from_now.overload2 expires_from_now]``(
+ const duration_type & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_from_now.overload2 more...]]``
+
+ std::size_t ``[link asio.reference.basic_deadline_timer.expires_from_now.overload3 expires_from_now]``(
+ const duration_type & expiry_time,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.expires_from_now.overload3 more...]]``
+
+
+[section:overload1 basic_deadline_timer::expires_from_now (1 of 3 overloads)]
+
+
+Get the timer's expiry time relative to now.
+
+
+ duration_type expires_from_now() const;
+
+
+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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::expires_from_now (2 of 3 overloads)]
+
+
+Set the timer's expiry time relative to now.
+
+
+ std::size_t expires_from_now(
+ const duration_type & expiry_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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_from_now()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload3 basic_deadline_timer::expires_from_now (3 of 3 overloads)]
+
+
+Set the timer's expiry time relative to now.
+
+
+ std::size_t expires_from_now(
+ const duration_type & expiry_time,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_from_now()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor basic_deadline_timer::get_executor]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.get_executor..get_executor..basic_deadline_timer]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_deadline_timer::get_io_context]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.get_io_context..get_io_context..basic_deadline_timer]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_deadline_timer::get_io_service]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.get_io_service..get_io_service..basic_deadline_timer]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ basic_deadline_timer::operator=]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.operator_eq_..operator=..basic_deadline_timer]
+Move-assign a [link asio.reference.basic_deadline_timer `basic_deadline_timer`] from another.
+
+
+ basic_deadline_timer & operator=(
+ basic_deadline_timer && other);
+
+
+This assignment operator moves a timer from one object to another. Cancels any outstanding asynchronous operations associated with the target object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_deadline_timer `basic_deadline_timer`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_deadline_timer(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:time_type basic_deadline_timer::time_type]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.time_type..time_type..basic_deadline_timer]
+The time type.
+
+
+ typedef traits_type::time_type time_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:traits_type basic_deadline_timer::traits_type]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.traits_type..traits_type..basic_deadline_timer]
+The time traits type.
+
+
+ typedef TimeTraits traits_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:wait basic_deadline_timer::wait]
+
+[indexterm2 asio.indexterm.basic_deadline_timer.wait..wait..basic_deadline_timer]
+Perform a blocking wait on the timer.
+
+
+ void ``[link asio.reference.basic_deadline_timer.wait.overload1 wait]``();
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_deadline_timer.wait.overload2 wait]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_deadline_timer.wait.overload2 more...]]``
+
+
+[section:overload1 basic_deadline_timer::wait (1 of 2 overloads)]
+
+
+Perform a blocking wait on the timer.
+
+
+ void wait();
+
+
+This function is used to wait for the timer to expire. This function blocks and does not return until the timer has expired.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_deadline_timer::wait (2 of 2 overloads)]
+
+
+Perform a blocking wait on the timer.
+
+
+ void wait(
+ asio::error_code & ec);
+
+
+This function is used to wait for the timer to expire. This function blocks and does not return until the timer has expired.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_basic_deadline_timer basic_deadline_timer::~basic_deadline_timer]
+
+[indexterm2 asio.indexterm.basic_deadline_timer._basic_deadline_timer..~basic_deadline_timer..basic_deadline_timer]
+Destroys the timer.
+
+
+ ~basic_deadline_timer();
+
+
+This function destroys the timer, cancelling any outstanding asynchronous wait operations associated with the timer as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_io_object basic_io_object]
+
+
+Base class for all I/O objects.
+
+
+ template<
+ typename ``[link asio.reference.IoObjectService IoObjectService]``>
+ class basic_io_object
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_io_object.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_io_object.implementation_type [*implementation_type]]]
+ [The underlying implementation type of I/O object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_io_object.service_type [*service_type]]]
+ [The type of the service that will be used to provide I/O operations. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_io_object.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_io_object.basic_io_object [*basic_io_object]]]
+ [Construct a basic_io_object.
+
+ Move-construct a basic_io_object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object.get_implementation [*get_implementation]]]
+ [Get the underlying implementation of the I/O object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object.get_service [*get_service]]]
+ [Get the service associated with the I/O object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object.operator_eq_ [*operator=]]]
+ [Move-assign a basic_io_object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_io_object._basic_io_object [*~basic_io_object]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+
+[heading Remarks]
+
+All I/O objects are non-copyable. However, when using C++0x, certain I/O objects do support move construction and move assignment.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_io_object.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_io_object basic_io_object::basic_io_object]
+
+[indexterm2 asio.indexterm.basic_io_object.basic_io_object..basic_io_object..basic_io_object]
+Construct a [link asio.reference.basic_io_object `basic_io_object`].
+
+
+ explicit ``[link asio.reference.basic_io_object.basic_io_object.overload1 basic_io_object]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.basic_io_object.overload1 more...]]``
+
+
+Move-construct a [link asio.reference.basic_io_object `basic_io_object`].
+
+
+ ``[link asio.reference.basic_io_object.basic_io_object.overload2 basic_io_object]``(
+ basic_io_object && other);
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.basic_io_object.overload2 more...]]``
+
+
+[section:overload1 basic_io_object::basic_io_object (1 of 2 overloads)]
+
+
+Construct a [link asio.reference.basic_io_object `basic_io_object`].
+
+
+ basic_io_object(
+ asio::io_context & io_context);
+
+
+Performs:
+
+ get_service().construct(get_implementation());
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_io_object::basic_io_object (2 of 2 overloads)]
+
+
+Move-construct a [link asio.reference.basic_io_object `basic_io_object`].
+
+
+ basic_io_object(
+ basic_io_object && other);
+
+
+Performs:
+
+ get_service().move_construct(
+ get_implementation(), other.get_implementation());
+
+
+
+
+
+[heading Remarks]
+
+Available only for services that support movability,
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type basic_io_object::executor_type]
+
+[indexterm2 asio.indexterm.basic_io_object.executor_type..executor_type..basic_io_object]
+The type of the executor associated with the object.
+
+
+ typedef asio::io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_io_object.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_io_object::get_executor]
+
+[indexterm2 asio.indexterm.basic_io_object.get_executor..get_executor..basic_io_object]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+[section:get_implementation basic_io_object::get_implementation]
+
+[indexterm2 asio.indexterm.basic_io_object.get_implementation..get_implementation..basic_io_object]
+Get the underlying implementation of the I/O object.
+
+
+ implementation_type & ``[link asio.reference.basic_io_object.get_implementation.overload1 get_implementation]``();
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.get_implementation.overload1 more...]]``
+
+ const implementation_type & ``[link asio.reference.basic_io_object.get_implementation.overload2 get_implementation]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.get_implementation.overload2 more...]]``
+
+
+[section:overload1 basic_io_object::get_implementation (1 of 2 overloads)]
+
+
+Get the underlying implementation of the I/O object.
+
+
+ implementation_type & get_implementation();
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_io_object::get_implementation (2 of 2 overloads)]
+
+
+Get the underlying implementation of the I/O object.
+
+
+ const implementation_type & get_implementation() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_io_context basic_io_object::get_io_context]
+
+[indexterm2 asio.indexterm.basic_io_object.get_io_context..get_io_context..basic_io_object]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_io_object::get_io_service]
+
+[indexterm2 asio.indexterm.basic_io_object.get_io_service..get_io_service..basic_io_object]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_service basic_io_object::get_service]
+
+[indexterm2 asio.indexterm.basic_io_object.get_service..get_service..basic_io_object]
+Get the service associated with the I/O object.
+
+
+ service_type & ``[link asio.reference.basic_io_object.get_service.overload1 get_service]``();
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.get_service.overload1 more...]]``
+
+ const service_type & ``[link asio.reference.basic_io_object.get_service.overload2 get_service]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_io_object.get_service.overload2 more...]]``
+
+
+[section:overload1 basic_io_object::get_service (1 of 2 overloads)]
+
+
+Get the service associated with the I/O object.
+
+
+ service_type & get_service();
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_io_object::get_service (2 of 2 overloads)]
+
+
+Get the service associated with the I/O object.
+
+
+ const service_type & get_service() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:implementation_type basic_io_object::implementation_type]
+
+[indexterm2 asio.indexterm.basic_io_object.implementation_type..implementation_type..basic_io_object]
+The underlying implementation type of I/O object.
+
+
+ typedef service_type::implementation_type implementation_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_io_object.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ basic_io_object::operator=]
+
+[indexterm2 asio.indexterm.basic_io_object.operator_eq_..operator=..basic_io_object]
+Move-assign a [link asio.reference.basic_io_object `basic_io_object`].
+
+
+ basic_io_object & operator=(
+ basic_io_object && other);
+
+
+Performs:
+
+ get_service().move_assign(get_implementation(),
+ other.get_service(), other.get_implementation());
+
+
+
+
+
+[heading Remarks]
+
+Available only for services that support movability,
+
+
+
+
+[endsect]
+
+
+
+[section:service_type basic_io_object::service_type]
+
+[indexterm2 asio.indexterm.basic_io_object.service_type..service_type..basic_io_object]
+The type of the service that will be used to provide I/O operations.
+
+
+ typedef IoObjectService service_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_io_object.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:_basic_io_object basic_io_object::~basic_io_object]
+
+[indexterm2 asio.indexterm.basic_io_object._basic_io_object..~basic_io_object..basic_io_object]
+Protected destructor to prevent deletion through this type.
+
+
+ ~basic_io_object();
+
+
+Performs:
+
+ get_service().destroy(get_implementation());
+
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_raw_socket basic_raw_socket]
+
+
+Provides raw-oriented socket functionality.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_raw_socket :
+ public basic_socket< Protocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.basic_raw_socket [*basic_raw_socket]]]
+ [Construct a basic_raw_socket without opening it.
+
+ Construct and open a basic_raw_socket.
+
+ Construct a basic_raw_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_raw_socket on an existing native socket.
+
+ Move-construct a basic_raw_socket from another.
+
+ Move-construct a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_raw_socket from another.
+
+ Move-assign a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive_from [*receive_from]]]
+ [Receive raw data with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send_to [*send_to]]]
+ [Send raw data to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket._basic_raw_socket [*~basic_raw_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_raw_socket `basic_raw_socket`] class template provides asynchronous and blocking raw-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign basic_raw_socket::assign]
+
+[indexterm2 asio.indexterm.basic_raw_socket.assign..assign..basic_raw_socket]
+Assign an existing native socket to the socket.
+
+
+ void ``[link asio.reference.basic_raw_socket.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.assign.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::assign (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::assign (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_connect basic_raw_socket::async_connect]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_connect..async_connect..basic_raw_socket]
+Start an asynchronous connect.
+
+
+ template<
+ typename ``[link asio.reference.ConnectHandler ConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ const endpoint_type & peer_endpoint,
+ ConnectHandler && handler);
+
+
+This function is used to asynchronously connect a socket to the specified remote endpoint. The function call always returns immediately.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected. Copies will be made of the endpoint object as required.]]
+
+[[handler][The handler to be called when the connection operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void connect_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Connect succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.async_connect(endpoint, connect_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:async_receive basic_raw_socket::async_receive]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_receive..async_receive..basic_raw_socket]
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_receive.overload1 async_receive]``(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_receive.overload2 async_receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_receive.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::async_receive (1 of 2 overloads)]
+
+
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the raw socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::async_receive (2 of 2 overloads)]
+
+
+Start an asynchronous receive on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the raw socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_receive_from basic_raw_socket::async_receive_from]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_receive_from..async_receive_from..basic_raw_socket]
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_receive_from.overload1 async_receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_receive_from.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_receive_from.overload2 async_receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_receive_from.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::async_receive_from (1 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive raw data. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive_from(
+ asio::buffer(data, size), 0, sender_endpoint, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::async_receive_from (2 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive raw data. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_send basic_raw_socket::async_send]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_send..async_send..basic_raw_socket]
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_send.overload1 async_send]``(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_send.overload2 async_send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_send.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::async_send (1 of 2 overloads)]
+
+
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_send(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::async_send (2 of 2 overloads)]
+
+
+Start an asynchronous send on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+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.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_send_to basic_raw_socket::async_send_to]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_send_to..async_send_to..basic_raw_socket]
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_send_to.overload1 async_send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_send_to.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_raw_socket.async_send_to.overload2 async_send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.async_send_to.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::async_send_to (1 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send raw data to the specified remote endpoint. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[destination][The remote endpoint to which the data will be sent. Copies will be made of the endpoint as required.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ 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);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::async_send_to (2 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send raw data to the specified remote endpoint. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[destination][The remote endpoint to which the data will be sent. Copies will be made of the endpoint as required.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait basic_raw_socket::async_wait]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.async_wait..async_wait..basic_raw_socket]
+Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:at_mark basic_raw_socket::at_mark]
+
+[indexterm2 asio.indexterm.basic_raw_socket.at_mark..at_mark..basic_raw_socket]
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool ``[link asio.reference.basic_raw_socket.at_mark.overload1 at_mark]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.at_mark.overload1 more...]]``
+
+ bool ``[link asio.reference.basic_raw_socket.at_mark.overload2 at_mark]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.at_mark.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::at_mark (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark() const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::at_mark (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark(
+ asio::error_code & ec) const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:available basic_raw_socket::available]
+
+[indexterm2 asio.indexterm.basic_raw_socket.available..available..basic_raw_socket]
+Determine the number of bytes available for reading.
+
+
+ std::size_t ``[link asio.reference.basic_raw_socket.available.overload1 available]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.available.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_raw_socket.available.overload2 available]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.available.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::available (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available() const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::available (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available(
+ asio::error_code & ec) const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_raw_socket basic_raw_socket::basic_raw_socket]
+
+[indexterm2 asio.indexterm.basic_raw_socket.basic_raw_socket..basic_raw_socket..basic_raw_socket]
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] without opening it.
+
+
+ explicit ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload1 basic_raw_socket]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.basic_raw_socket `basic_raw_socket`].
+
+
+ ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload2 basic_raw_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload2 more...]]``
+
+
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`], opening it and binding it to the given local endpoint.
+
+
+ ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload3 basic_raw_socket]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] on an existing native socket.
+
+
+ ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload4 basic_raw_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] from another.
+
+
+ ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload5 basic_raw_socket]``(
+ basic_raw_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_raw_socket.basic_raw_socket.overload6 basic_raw_socket]``(
+ basic_raw_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.basic_raw_socket.overload6 more...]]``
+
+
+[section:overload1 basic_raw_socket::basic_raw_socket (1 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] without opening it.
+
+
+ basic_raw_socket(
+ asio::io_context & io_context);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the raw socket will use to dispatch handlers for any asynchronous operations performed on the socket. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::basic_raw_socket (2 of 6 overloads)]
+
+
+Construct and open a [link asio.reference.basic_raw_socket `basic_raw_socket`].
+
+
+ basic_raw_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates and opens a raw socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the raw socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::basic_raw_socket (3 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`], opening it and binding it to the given local endpoint.
+
+
+ basic_raw_socket(
+ asio::io_context & io_context,
+ const endpoint_type & 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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the raw socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[endpoint][An endpoint on the local machine to which the raw socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_raw_socket::basic_raw_socket (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] on an existing native socket.
+
+
+ basic_raw_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+This constructor creates a raw socket object to hold an existing native socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the raw socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_socket][The new underlying socket implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_raw_socket::basic_raw_socket (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] from another.
+
+
+ basic_raw_socket(
+ basic_raw_socket && other);
+
+
+This constructor moves a raw socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_raw_socket `basic_raw_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_raw_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_raw_socket::basic_raw_socket (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_raw_socket `basic_raw_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_raw_socket(
+ basic_raw_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves a raw socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_raw_socket `basic_raw_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_raw_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_raw_socket::bind]
+
+[indexterm2 asio.indexterm.basic_raw_socket.bind..bind..basic_raw_socket]
+Bind the socket to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_raw_socket.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.bind.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::bind (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::bind (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ asio::error_code ec;
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_raw_socket::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.broadcast..broadcast..basic_raw_socket]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_raw_socket::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.bytes_readable..bytes_readable..basic_raw_socket]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_raw_socket::cancel]
+
+[indexterm2 asio.indexterm.basic_raw_socket.cancel..cancel..basic_raw_socket]
+Cancel all asynchronous operations associated with the socket.
+
+
+ void ``[link asio.reference.basic_raw_socket.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::cancel (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::cancel (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_raw_socket::close]
+
+[indexterm2 asio.indexterm.basic_raw_socket.close..close..basic_raw_socket]
+Close the socket.
+
+
+ void ``[link asio.reference.basic_raw_socket.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.close.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::close (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close();
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::close (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:connect basic_raw_socket::connect]
+
+[indexterm2 asio.indexterm.basic_raw_socket.connect..connect..basic_raw_socket]
+Connect the socket to the specified endpoint.
+
+
+ void ``[link asio.reference.basic_raw_socket.connect.overload1 connect]``(
+ const endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.connect.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.connect.overload2 connect]``(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.connect.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::connect (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.connect(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::connect (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ asio::error_code ec;
+ socket.connect(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_raw_socket::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.debug..debug..basic_raw_socket]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_raw_socket::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.do_not_route..do_not_route..basic_raw_socket]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_raw_socket::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.enable_connection_aborted..enable_connection_aborted..basic_raw_socket]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_raw_socket::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_raw_socket.endpoint_type..endpoint_type..basic_raw_socket]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_raw_socket::executor_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.executor_type..executor_type..basic_raw_socket]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_raw_socket::get_executor]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.get_executor..get_executor..basic_raw_socket]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_raw_socket::get_io_context]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.get_io_context..get_io_context..basic_raw_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_raw_socket::get_io_service]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.get_io_service..get_io_service..basic_raw_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_raw_socket::get_option]
+
+[indexterm2 asio.indexterm.basic_raw_socket.get_option..get_option..basic_raw_socket]
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_raw_socket.get_option.overload1 get_option]``(
+ GettableSocketOption & option) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_raw_socket.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::get_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::get_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ asio::error_code ec;
+ socket.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_raw_socket::io_control]
+
+[indexterm2 asio.indexterm.basic_raw_socket.io_control..io_control..basic_raw_socket]
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_raw_socket.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_raw_socket.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::io_control (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::io_control (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_raw_socket::is_open]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.is_open..is_open..basic_raw_socket]
+Determine whether the socket is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_raw_socket::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.keep_alive..keep_alive..basic_raw_socket]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_raw_socket::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.linger..linger..basic_raw_socket]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:local_endpoint basic_raw_socket::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_raw_socket.local_endpoint..local_endpoint..basic_raw_socket]
+Get the local endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_raw_socket.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_raw_socket.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::local_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::local_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer basic_raw_socket::lowest_layer]
+
+[indexterm2 asio.indexterm.basic_raw_socket.lowest_layer..lowest_layer..basic_raw_socket]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.basic_raw_socket.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.basic_raw_socket.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type basic_raw_socket::lowest_layer_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.lowest_layer_type..lowest_layer_type..basic_raw_socket]
+A [link asio.reference.basic_socket `basic_socket`] is always the lowest layer.
+
+
+ typedef basic_socket< Protocol > lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections basic_raw_socket::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.max_connections..max_connections..basic_raw_socket]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_raw_socket::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.max_listen_connections..max_listen_connections..basic_raw_socket]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_raw_socket::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.message_do_not_route..message_do_not_route..basic_raw_socket]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_raw_socket::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.message_end_of_record..message_end_of_record..basic_raw_socket]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_raw_socket::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.message_flags..message_flags..basic_raw_socket]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_raw_socket::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.message_out_of_band..message_out_of_band..basic_raw_socket]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_raw_socket::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.message_peek..message_peek..basic_raw_socket]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_raw_socket::native_handle]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.native_handle..native_handle..basic_raw_socket]
+Get the native socket representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the socket. This is intended to allow access to native socket functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_raw_socket::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_raw_socket.native_handle_type..native_handle_type..basic_raw_socket]
+The native representation of a socket.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_raw_socket::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_raw_socket.native_non_blocking..native_non_blocking..basic_raw_socket]
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool ``[link asio.reference.basic_raw_socket.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void ``[link asio.reference.basic_raw_socket.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::native_non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native socket. This mode has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying socket is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the socket object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native socket.
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::native_non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::native_non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_raw_socket::non_blocking]
+
+[indexterm2 asio.indexterm.basic_raw_socket.non_blocking..non_blocking..basic_raw_socket]
+Gets the non-blocking mode of the socket.
+
+
+ bool ``[link asio.reference.basic_raw_socket.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void ``[link asio.reference.basic_raw_socket.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the socket.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_raw_socket::open]
+
+[indexterm2 asio.indexterm.basic_raw_socket.open..open..basic_raw_socket]
+Open the socket using the specified protocol.
+
+
+ void ``[link asio.reference.basic_raw_socket.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.open.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::open (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::open (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ socket.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_raw_socket::operator=]
+
+[indexterm2 asio.indexterm.basic_raw_socket.operator_eq_..operator=..basic_raw_socket]
+Move-assign a [link asio.reference.basic_raw_socket `basic_raw_socket`] from another.
+
+
+ basic_raw_socket & ``[link asio.reference.basic_raw_socket.operator_eq_.overload1 operator=]``(
+ basic_raw_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_raw_socket `basic_raw_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_raw_socket >::type & ``[link asio.reference.basic_raw_socket.operator_eq_.overload2 operator=]``(
+ basic_raw_socket< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_raw_socket `basic_raw_socket`] from another.
+
+
+ basic_raw_socket & operator=(
+ basic_raw_socket && other);
+
+
+This assignment operator moves a raw socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_raw_socket `basic_raw_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_raw_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_raw_socket `basic_raw_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_raw_socket >::type & operator=(
+ basic_raw_socket< Protocol1 > && other);
+
+
+This assignment operator moves a raw socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_raw_socket `basic_raw_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_raw_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_raw_socket::protocol_type]
+
+[indexterm2 asio.indexterm.basic_raw_socket.protocol_type..protocol_type..basic_raw_socket]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:receive basic_raw_socket::receive]
+
+[indexterm2 asio.indexterm.basic_raw_socket.receive..receive..basic_raw_socket]
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive.overload1 receive]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive.overload2 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive.overload3 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::receive (1 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected raw socket.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::receive (2 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected raw socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::receive (3 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Remarks]
+
+The receive operation can only be used with a connected socket. Use the receive\_from function to receive data on an unconnected raw socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_buffer_size basic_raw_socket::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.receive_buffer_size..receive_buffer_size..basic_raw_socket]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:receive_from basic_raw_socket::receive_from]
+
+[indexterm2 asio.indexterm.basic_raw_socket.receive_from..receive_from..basic_raw_socket]
+Receive raw data with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive_from.overload1 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive_from.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive_from.overload2 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive_from.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.receive_from.overload3 receive_from]``(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.receive_from.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::receive_from (1 of 3 overloads)]
+
+
+Receive raw data with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint);
+
+
+This function is used to receive raw data. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the data.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::ip::udp::endpoint sender_endpoint;
+ socket.receive_from(
+ asio::buffer(data, size), sender_endpoint);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::receive_from (2 of 3 overloads)]
+
+
+Receive raw data with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags);
+
+
+This function is used to receive raw data. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the data.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::receive_from (3 of 3 overloads)]
+
+
+Receive raw data with the endpoint of the sender.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive_from(
+ const MutableBufferSequence & buffers,
+ endpoint_type & sender_endpoint,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+This function is used to receive raw data. The function call will block until data has been received successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[sender_endpoint][An endpoint object that receives the endpoint of the remote sender of the data.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_low_watermark basic_raw_socket::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.receive_low_watermark..receive_low_watermark..basic_raw_socket]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:remote_endpoint basic_raw_socket::remote_endpoint]
+
+[indexterm2 asio.indexterm.basic_raw_socket.remote_endpoint..remote_endpoint..basic_raw_socket]
+Get the remote endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_raw_socket.remote_endpoint.overload1 remote_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.remote_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_raw_socket.remote_endpoint.overload2 remote_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.remote_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::remote_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint() const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::remote_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:reuse_address basic_raw_socket::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.reuse_address..reuse_address..basic_raw_socket]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send basic_raw_socket::send]
+
+[indexterm2 asio.indexterm.basic_raw_socket.send..send..basic_raw_socket]
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send.overload1 send]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send.overload2 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send.overload3 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::send (1 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One ore more data buffers to be sent on the socket.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected raw socket.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.send(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::send (2 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One ore more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected raw socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::send (3 of 3 overloads)]
+
+
+Send some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Remarks]
+
+The send operation can only be used with a connected socket. Use the send\_to function to send data on an unconnected raw socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:send_buffer_size basic_raw_socket::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.send_buffer_size..send_buffer_size..basic_raw_socket]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_raw_socket::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.send_low_watermark..send_low_watermark..basic_raw_socket]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_raw_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send_to basic_raw_socket::send_to]
+
+[indexterm2 asio.indexterm.basic_raw_socket.send_to..send_to..basic_raw_socket]
+Send raw data to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send_to.overload1 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send_to.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send_to.overload2 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send_to.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_raw_socket.send_to.overload3 send_to]``(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.send_to.overload3 more...]]``
+
+
+[section:overload1 basic_raw_socket::send_to (1 of 3 overloads)]
+
+
+Send raw data to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::ip::udp::endpoint destination(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.send_to(asio::buffer(data, size), destination);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::send_to (2 of 3 overloads)]
+
+
+Send raw data to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_raw_socket::send_to (3 of 3 overloads)]
+
+
+Send raw data to the specified endpoint.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send_to(
+ const ConstBufferSequence & buffers,
+ const endpoint_type & destination,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent to the remote endpoint.]]
+
+[[destination][The remote endpoint to which the data will be sent.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_option basic_raw_socket::set_option]
+
+[indexterm2 asio.indexterm.basic_raw_socket.set_option..set_option..basic_raw_socket]
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_raw_socket.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_raw_socket.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::set_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::set_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ asio::error_code ec;
+ socket.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown basic_raw_socket::shutdown]
+
+[indexterm2 asio.indexterm.basic_raw_socket.shutdown..shutdown..basic_raw_socket]
+Disable sends or receives on the socket.
+
+
+ void ``[link asio.reference.basic_raw_socket.shutdown.overload1 shutdown]``(
+ shutdown_type what);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.shutdown.overload2 shutdown]``(
+ shutdown_type what,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.shutdown.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::shutdown (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::shutdown (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what,
+ asio::error_code & ec);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_raw_socket::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.shutdown_type..shutdown_type..basic_raw_socket]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_raw_socket.shutdown_type.shutdown_receive..shutdown_receive..basic_raw_socket]
+[indexterm2 asio.indexterm.basic_raw_socket.shutdown_type.shutdown_send..shutdown_send..basic_raw_socket]
+[indexterm2 asio.indexterm.basic_raw_socket.shutdown_type.shutdown_both..shutdown_both..basic_raw_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_raw_socket::wait]
+
+[indexterm2 asio.indexterm.basic_raw_socket.wait..wait..basic_raw_socket]
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_raw_socket.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_raw_socket.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_raw_socket.wait.overload2 more...]]``
+
+
+[section:overload1 basic_raw_socket::wait (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.wait(asio::ip::tcp::socket::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_raw_socket::wait (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.wait(asio::ip::tcp::socket::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_raw_socket::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_raw_socket.wait_type..wait_type..basic_raw_socket]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_raw_socket.wait_type.wait_read..wait_read..basic_raw_socket]
+[indexterm2 asio.indexterm.basic_raw_socket.wait_type.wait_write..wait_write..basic_raw_socket]
+[indexterm2 asio.indexterm.basic_raw_socket.wait_type.wait_error..wait_error..basic_raw_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_basic_raw_socket basic_raw_socket::~basic_raw_socket]
+
+[indexterm2 asio.indexterm.basic_raw_socket._basic_raw_socket..~basic_raw_socket..basic_raw_socket]
+Destroys the socket.
+
+
+ ~basic_raw_socket();
+
+
+This function destroys the socket, cancelling any outstanding asynchronous operations associated with the socket as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_seq_packet_socket basic_seq_packet_socket]
+
+
+Provides sequenced packet socket functionality.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_seq_packet_socket :
+ public basic_socket< Protocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket [*basic_seq_packet_socket]]]
+ [Construct a basic_seq_packet_socket without opening it.
+
+ Construct and open a basic_seq_packet_socket.
+
+ Construct a basic_seq_packet_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_seq_packet_socket on an existing native socket.
+
+ Move-construct a basic_seq_packet_socket from another.
+
+ Move-construct a basic_seq_packet_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_seq_packet_socket from another.
+
+ Move-assign a basic_seq_packet_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket._basic_seq_packet_socket [*~basic_seq_packet_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] class template provides asynchronous and blocking sequenced packet socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign basic_seq_packet_socket::assign]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.assign..assign..basic_seq_packet_socket]
+Assign an existing native socket to the socket.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.assign.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::assign (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::assign (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_connect basic_seq_packet_socket::async_connect]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.async_connect..async_connect..basic_seq_packet_socket]
+Start an asynchronous connect.
+
+
+ template<
+ typename ``[link asio.reference.ConnectHandler ConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ const endpoint_type & peer_endpoint,
+ ConnectHandler && handler);
+
+
+This function is used to asynchronously connect a socket to the specified remote endpoint. The function call always returns immediately.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected. Copies will be made of the endpoint object as required.]]
+
+[[handler][The handler to be called when the connection operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void connect_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Connect succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.async_connect(endpoint, connect_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:async_receive basic_seq_packet_socket::async_receive]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.async_receive..async_receive..basic_seq_packet_socket]
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_seq_packet_socket.async_receive.overload1 async_receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags & out_flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.async_receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_seq_packet_socket.async_receive.overload2 async_receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.async_receive.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::async_receive (1 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags & out_flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the sequenced packet socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[out_flags][Once the asynchronous operation completes, contains flags associated with the received data. For example, if the `socket_base::message_end_of_record` bit is set then the received data marks the end of a record. The caller must guarantee that the referenced variable remains valid until the handler is called.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(asio::buffer(data, size), out_flags, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::async_receive (2 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the sequenced data socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[in_flags][Flags specifying how the receive call is to be made.]]
+
+[[out_flags][Once the asynchronous operation completes, contains flags associated with the received data. For example, if the `socket_base::message_end_of_record` bit is set then the received data marks the end of a record. The caller must guarantee that the referenced variable remains valid until the handler is called.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(
+ asio::buffer(data, size),
+ 0, out_flags, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_send basic_seq_packet_socket::async_send]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.async_send..async_send..basic_seq_packet_socket]
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send data on the sequenced packet socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_send(asio::buffer(data, size), 0, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:async_wait basic_seq_packet_socket::async_wait]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.async_wait..async_wait..basic_seq_packet_socket]
+Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:at_mark basic_seq_packet_socket::at_mark]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.at_mark..at_mark..basic_seq_packet_socket]
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool ``[link asio.reference.basic_seq_packet_socket.at_mark.overload1 at_mark]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.at_mark.overload1 more...]]``
+
+ bool ``[link asio.reference.basic_seq_packet_socket.at_mark.overload2 at_mark]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.at_mark.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::at_mark (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark() const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::at_mark (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark(
+ asio::error_code & ec) const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:available basic_seq_packet_socket::available]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.available..available..basic_seq_packet_socket]
+Determine the number of bytes available for reading.
+
+
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.available.overload1 available]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.available.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.available.overload2 available]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.available.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::available (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available() const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::available (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available(
+ asio::error_code & ec) const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_seq_packet_socket basic_seq_packet_socket::basic_seq_packet_socket]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.basic_seq_packet_socket..basic_seq_packet_socket..basic_seq_packet_socket]
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] without opening it.
+
+
+ explicit ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload1 basic_seq_packet_socket]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`].
+
+
+ ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload2 basic_seq_packet_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload2 more...]]``
+
+
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`], opening it and binding it to the given local endpoint.
+
+
+ ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload3 basic_seq_packet_socket]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] on an existing native socket.
+
+
+ ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload4 basic_seq_packet_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from another.
+
+
+ ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload5 basic_seq_packet_socket]``(
+ basic_seq_packet_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload6 basic_seq_packet_socket]``(
+ basic_seq_packet_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket.overload6 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::basic_seq_packet_socket (1 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] without opening it.
+
+
+ basic_seq_packet_socket(
+ asio::io_context & io_context);
+
+
+This constructor creates a sequenced packet socket without opening it. The socket needs to be opened and then connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the sequenced packet socket will use to dispatch handlers for any asynchronous operations performed on the socket. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::basic_seq_packet_socket (2 of 6 overloads)]
+
+
+Construct and open a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`].
+
+
+ basic_seq_packet_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates and opens a sequenced\_packet socket. The socket needs to be connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the sequenced packet socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_seq_packet_socket::basic_seq_packet_socket (3 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`], opening it and binding it to the given local endpoint.
+
+
+ basic_seq_packet_socket(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+
+
+This constructor creates a sequenced packet 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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the sequenced packet socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[endpoint][An endpoint on the local machine to which the sequenced packet socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_seq_packet_socket::basic_seq_packet_socket (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] on an existing native socket.
+
+
+ basic_seq_packet_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+This constructor creates a sequenced packet socket object to hold an existing native socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the sequenced packet socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_socket][The new underlying socket implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_seq_packet_socket::basic_seq_packet_socket (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from another.
+
+
+ basic_seq_packet_socket(
+ basic_seq_packet_socket && other);
+
+
+This constructor moves a sequenced packet socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_seq_packet_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_seq_packet_socket::basic_seq_packet_socket (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_seq_packet_socket(
+ basic_seq_packet_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves a sequenced packet socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_seq_packet_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_seq_packet_socket::bind]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.bind..bind..basic_seq_packet_socket]
+Bind the socket to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.bind.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::bind (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::bind (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ asio::error_code ec;
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_seq_packet_socket::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.broadcast..broadcast..basic_seq_packet_socket]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_seq_packet_socket::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.bytes_readable..bytes_readable..basic_seq_packet_socket]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_seq_packet_socket::cancel]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.cancel..cancel..basic_seq_packet_socket]
+Cancel all asynchronous operations associated with the socket.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::cancel (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::cancel (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_seq_packet_socket::close]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.close..close..basic_seq_packet_socket]
+Close the socket.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.close.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::close (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close();
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::close (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:connect basic_seq_packet_socket::connect]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.connect..connect..basic_seq_packet_socket]
+Connect the socket to the specified endpoint.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.connect.overload1 connect]``(
+ const endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.connect.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.connect.overload2 connect]``(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.connect.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::connect (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.connect(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::connect (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ asio::error_code ec;
+ socket.connect(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_seq_packet_socket::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.debug..debug..basic_seq_packet_socket]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_seq_packet_socket::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.do_not_route..do_not_route..basic_seq_packet_socket]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_seq_packet_socket::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.enable_connection_aborted..enable_connection_aborted..basic_seq_packet_socket]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_seq_packet_socket::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.endpoint_type..endpoint_type..basic_seq_packet_socket]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_seq_packet_socket::executor_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.executor_type..executor_type..basic_seq_packet_socket]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_seq_packet_socket::get_executor]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.get_executor..get_executor..basic_seq_packet_socket]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_seq_packet_socket::get_io_context]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.get_io_context..get_io_context..basic_seq_packet_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_seq_packet_socket::get_io_service]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.get_io_service..get_io_service..basic_seq_packet_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_seq_packet_socket::get_option]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.get_option..get_option..basic_seq_packet_socket]
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_seq_packet_socket.get_option.overload1 get_option]``(
+ GettableSocketOption & option) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_seq_packet_socket.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::get_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::get_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ asio::error_code ec;
+ socket.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_seq_packet_socket::io_control]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.io_control..io_control..basic_seq_packet_socket]
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_seq_packet_socket.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_seq_packet_socket.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::io_control (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::io_control (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_seq_packet_socket::is_open]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.is_open..is_open..basic_seq_packet_socket]
+Determine whether the socket is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_seq_packet_socket::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.keep_alive..keep_alive..basic_seq_packet_socket]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_seq_packet_socket::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.linger..linger..basic_seq_packet_socket]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:local_endpoint basic_seq_packet_socket::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.local_endpoint..local_endpoint..basic_seq_packet_socket]
+Get the local endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_seq_packet_socket.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_seq_packet_socket.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::local_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::local_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer basic_seq_packet_socket::lowest_layer]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.lowest_layer..lowest_layer..basic_seq_packet_socket]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.basic_seq_packet_socket.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.basic_seq_packet_socket.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type basic_seq_packet_socket::lowest_layer_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.lowest_layer_type..lowest_layer_type..basic_seq_packet_socket]
+A [link asio.reference.basic_socket `basic_socket`] is always the lowest layer.
+
+
+ typedef basic_socket< Protocol > lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections basic_seq_packet_socket::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.max_connections..max_connections..basic_seq_packet_socket]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_seq_packet_socket::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.max_listen_connections..max_listen_connections..basic_seq_packet_socket]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_seq_packet_socket::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.message_do_not_route..message_do_not_route..basic_seq_packet_socket]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_seq_packet_socket::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.message_end_of_record..message_end_of_record..basic_seq_packet_socket]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_seq_packet_socket::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.message_flags..message_flags..basic_seq_packet_socket]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_seq_packet_socket::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.message_out_of_band..message_out_of_band..basic_seq_packet_socket]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_seq_packet_socket::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.message_peek..message_peek..basic_seq_packet_socket]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_seq_packet_socket::native_handle]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.native_handle..native_handle..basic_seq_packet_socket]
+Get the native socket representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the socket. This is intended to allow access to native socket functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_seq_packet_socket::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.native_handle_type..native_handle_type..basic_seq_packet_socket]
+The native representation of a socket.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_seq_packet_socket::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.native_non_blocking..native_non_blocking..basic_seq_packet_socket]
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool ``[link asio.reference.basic_seq_packet_socket.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::native_non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native socket. This mode has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying socket is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the socket object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native socket.
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::native_non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_seq_packet_socket::native_non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_seq_packet_socket::non_blocking]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.non_blocking..non_blocking..basic_seq_packet_socket]
+Gets the non-blocking mode of the socket.
+
+
+ bool ``[link asio.reference.basic_seq_packet_socket.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the socket.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_seq_packet_socket::non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_seq_packet_socket::open]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.open..open..basic_seq_packet_socket]
+Open the socket using the specified protocol.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.open.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::open (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::open (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ socket.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_seq_packet_socket::operator=]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.operator_eq_..operator=..basic_seq_packet_socket]
+Move-assign a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from another.
+
+
+ basic_seq_packet_socket & ``[link asio.reference.basic_seq_packet_socket.operator_eq_.overload1 operator=]``(
+ basic_seq_packet_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_seq_packet_socket >::type & ``[link asio.reference.basic_seq_packet_socket.operator_eq_.overload2 operator=]``(
+ basic_seq_packet_socket< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from another.
+
+
+ basic_seq_packet_socket & operator=(
+ basic_seq_packet_socket && other);
+
+
+This assignment operator moves a sequenced packet socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_seq_packet_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_seq_packet_socket >::type & operator=(
+ basic_seq_packet_socket< Protocol1 > && other);
+
+
+This assignment operator moves a sequenced packet socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_seq_packet_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_seq_packet_socket::protocol_type]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.protocol_type..protocol_type..basic_seq_packet_socket]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:receive basic_seq_packet_socket::receive]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.receive..receive..basic_seq_packet_socket]
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.receive.overload1 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags & out_flags);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.receive.overload2 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.receive.overload2 more...]]``
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.receive.overload3 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.receive.overload3 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::receive (1 of 3 overloads)]
+
+
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags & out_flags);
+
+
+This function is used to receive data on the sequenced packet socket. The function call will block until data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[out_flags][After the receive call completes, contains flags associated with the received data. For example, if the `socket_base::message_end_of_record` bit is set then the received data marks the end of a record.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size), out_flags);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::receive (2 of 3 overloads)]
+
+
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags);
+
+
+This function is used to receive data on the sequenced packet socket. The function call will block until data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[in_flags][Flags specifying how the receive call is to be made.]]
+
+[[out_flags][After the receive call completes, contains flags associated with the received data. For example, if the `socket_base::message_end_of_record` bit is set then the received data marks the end of a record.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size), 0, out_flags);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_seq_packet_socket::receive (3 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags & out_flags,
+ asio::error_code & ec);
+
+
+This function is used to receive data on the sequenced packet socket. The function call will block until data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[in_flags][Flags specifying how the receive call is to be made.]]
+
+[[out_flags][After the receive call completes, contains flags associated with the received data. For example, if the `socket_base::message_end_of_record` bit is set then the received data marks the end of a record.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_buffer_size basic_seq_packet_socket::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.receive_buffer_size..receive_buffer_size..basic_seq_packet_socket]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_low_watermark basic_seq_packet_socket::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.receive_low_watermark..receive_low_watermark..basic_seq_packet_socket]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:remote_endpoint basic_seq_packet_socket::remote_endpoint]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.remote_endpoint..remote_endpoint..basic_seq_packet_socket]
+Get the remote endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_seq_packet_socket.remote_endpoint.overload1 remote_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.remote_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_seq_packet_socket.remote_endpoint.overload2 remote_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.remote_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::remote_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint() const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::remote_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:reuse_address basic_seq_packet_socket::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.reuse_address..reuse_address..basic_seq_packet_socket]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send basic_seq_packet_socket::send]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.send..send..basic_seq_packet_socket]
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.send.overload1 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_seq_packet_socket.send.overload2 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.send.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::send (1 of 2 overloads)]
+
+
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+This function is used to send data on the sequenced packet socket. The function call will block until the data has been sent successfully, or an until error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.send(asio::buffer(data, size), 0);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::send (2 of 2 overloads)]
+
+
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+This function is used to send data on the sequenced packet socket. The function call will block the data has been sent successfully, or an until error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:send_buffer_size basic_seq_packet_socket::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.send_buffer_size..send_buffer_size..basic_seq_packet_socket]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_seq_packet_socket::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.send_low_watermark..send_low_watermark..basic_seq_packet_socket]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_seq_packet_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:set_option basic_seq_packet_socket::set_option]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.set_option..set_option..basic_seq_packet_socket]
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_seq_packet_socket.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_seq_packet_socket.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::set_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::set_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ asio::error_code ec;
+ socket.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown basic_seq_packet_socket::shutdown]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.shutdown..shutdown..basic_seq_packet_socket]
+Disable sends or receives on the socket.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.shutdown.overload1 shutdown]``(
+ shutdown_type what);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.shutdown.overload2 shutdown]``(
+ shutdown_type what,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.shutdown.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::shutdown (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::shutdown (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what,
+ asio::error_code & ec);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_seq_packet_socket::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.shutdown_type..shutdown_type..basic_seq_packet_socket]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.shutdown_type.shutdown_receive..shutdown_receive..basic_seq_packet_socket]
+[indexterm2 asio.indexterm.basic_seq_packet_socket.shutdown_type.shutdown_send..shutdown_send..basic_seq_packet_socket]
+[indexterm2 asio.indexterm.basic_seq_packet_socket.shutdown_type.shutdown_both..shutdown_both..basic_seq_packet_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_seq_packet_socket::wait]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.wait..wait..basic_seq_packet_socket]
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_seq_packet_socket.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_seq_packet_socket.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_seq_packet_socket.wait.overload2 more...]]``
+
+
+[section:overload1 basic_seq_packet_socket::wait (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.wait(asio::ip::tcp::socket::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_seq_packet_socket::wait (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.wait(asio::ip::tcp::socket::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_seq_packet_socket::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.wait_type..wait_type..basic_seq_packet_socket]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket.wait_type.wait_read..wait_read..basic_seq_packet_socket]
+[indexterm2 asio.indexterm.basic_seq_packet_socket.wait_type.wait_write..wait_write..basic_seq_packet_socket]
+[indexterm2 asio.indexterm.basic_seq_packet_socket.wait_type.wait_error..wait_error..basic_seq_packet_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_basic_seq_packet_socket basic_seq_packet_socket::~basic_seq_packet_socket]
+
+[indexterm2 asio.indexterm.basic_seq_packet_socket._basic_seq_packet_socket..~basic_seq_packet_socket..basic_seq_packet_socket]
+Destroys the socket.
+
+
+ ~basic_seq_packet_socket();
+
+
+This function destroys the socket, cancelling any outstanding asynchronous operations associated with the socket as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_socket basic_socket]
+
+
+Provides socket functionality.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_socket :
+ public socket_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign basic_socket::assign]
+
+[indexterm2 asio.indexterm.basic_socket.assign..assign..basic_socket]
+Assign an existing native socket to the socket.
+
+
+ void ``[link asio.reference.basic_socket.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.assign.overload2 more...]]``
+
+
+[section:overload1 basic_socket::assign (1 of 2 overloads)]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::assign (2 of 2 overloads)]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_connect basic_socket::async_connect]
+
+[indexterm2 asio.indexterm.basic_socket.async_connect..async_connect..basic_socket]
+Start an asynchronous connect.
+
+
+ template<
+ typename ``[link asio.reference.ConnectHandler ConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ const endpoint_type & peer_endpoint,
+ ConnectHandler && handler);
+
+
+This function is used to asynchronously connect a socket to the specified remote endpoint. The function call always returns immediately.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected. Copies will be made of the endpoint object as required.]]
+
+[[handler][The handler to be called when the connection operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void connect_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Connect succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.async_connect(endpoint, connect_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:async_wait basic_socket::async_wait]
+
+[indexterm2 asio.indexterm.basic_socket.async_wait..async_wait..basic_socket]
+Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:at_mark basic_socket::at_mark]
+
+[indexterm2 asio.indexterm.basic_socket.at_mark..at_mark..basic_socket]
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool ``[link asio.reference.basic_socket.at_mark.overload1 at_mark]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.at_mark.overload1 more...]]``
+
+ bool ``[link asio.reference.basic_socket.at_mark.overload2 at_mark]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.at_mark.overload2 more...]]``
+
+
+[section:overload1 basic_socket::at_mark (1 of 2 overloads)]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark() const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::at_mark (2 of 2 overloads)]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark(
+ asio::error_code & ec) const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:available basic_socket::available]
+
+[indexterm2 asio.indexterm.basic_socket.available..available..basic_socket]
+Determine the number of bytes available for reading.
+
+
+ std::size_t ``[link asio.reference.basic_socket.available.overload1 available]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.available.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_socket.available.overload2 available]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.available.overload2 more...]]``
+
+
+[section:overload1 basic_socket::available (1 of 2 overloads)]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available() const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::available (2 of 2 overloads)]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available(
+ asio::error_code & ec) const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_socket basic_socket::basic_socket]
+
+[indexterm2 asio.indexterm.basic_socket.basic_socket..basic_socket..basic_socket]
+Construct a [link asio.reference.basic_socket `basic_socket`] without opening it.
+
+
+ explicit ``[link asio.reference.basic_socket.basic_socket.overload1 basic_socket]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.basic_socket `basic_socket`].
+
+
+ ``[link asio.reference.basic_socket.basic_socket.overload2 basic_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload2 more...]]``
+
+
+Construct a [link asio.reference.basic_socket `basic_socket`], opening it and binding it to the given local endpoint.
+
+
+ ``[link asio.reference.basic_socket.basic_socket.overload3 basic_socket]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_socket `basic_socket`] on an existing native socket.
+
+
+ ``[link asio.reference.basic_socket.basic_socket.overload4 basic_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket `basic_socket`] from another.
+
+
+ ``[link asio.reference.basic_socket.basic_socket.overload5 basic_socket]``(
+ basic_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket `basic_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_socket.basic_socket.overload6 basic_socket]``(
+ basic_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.basic_socket.overload6 more...]]``
+
+
+[section:overload1 basic_socket::basic_socket (1 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_socket `basic_socket`] without opening it.
+
+
+ basic_socket(
+ asio::io_context & io_context);
+
+
+This constructor creates a socket without opening it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the socket will use to dispatch handlers for any asynchronous operations performed on the socket. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::basic_socket (2 of 6 overloads)]
+
+
+Construct and open a [link asio.reference.basic_socket `basic_socket`].
+
+
+ basic_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates and opens a socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket::basic_socket (3 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_socket `basic_socket`], opening it and binding it to the given local endpoint.
+
+
+ basic_socket(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+
+
+This constructor creates a socket and automatically opens it bound to the specified endpoint on the local machine. The protocol used is the protocol associated with the given endpoint.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_socket::basic_socket (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_socket `basic_socket`] on an existing native socket.
+
+
+ basic_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+This constructor creates a socket object to hold an existing native socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_socket][A native socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_socket::basic_socket (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket `basic_socket`] from another.
+
+
+ basic_socket(
+ basic_socket && other);
+
+
+This constructor moves a socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket `basic_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_socket::basic_socket (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket `basic_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_socket(
+ basic_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves a socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket `basic_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_socket::bind]
+
+[indexterm2 asio.indexterm.basic_socket.bind..bind..basic_socket]
+Bind the socket to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_socket.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.bind.overload2 more...]]``
+
+
+[section:overload1 basic_socket::bind (1 of 2 overloads)]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::bind (2 of 2 overloads)]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ asio::error_code ec;
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_socket::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.broadcast..broadcast..basic_socket]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_socket::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.bytes_readable..bytes_readable..basic_socket]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_socket::cancel]
+
+[indexterm2 asio.indexterm.basic_socket.cancel..cancel..basic_socket]
+Cancel all asynchronous operations associated with the socket.
+
+
+ void ``[link asio.reference.basic_socket.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_socket::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_socket::close]
+
+[indexterm2 asio.indexterm.basic_socket.close..close..basic_socket]
+Close the socket.
+
+
+ void ``[link asio.reference.basic_socket.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.close.overload2 more...]]``
+
+
+[section:overload1 basic_socket::close (1 of 2 overloads)]
+
+
+Close the socket.
+
+
+ void close();
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::close (2 of 2 overloads)]
+
+
+Close the socket.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:connect basic_socket::connect]
+
+[indexterm2 asio.indexterm.basic_socket.connect..connect..basic_socket]
+Connect the socket to the specified endpoint.
+
+
+ void ``[link asio.reference.basic_socket.connect.overload1 connect]``(
+ const endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.connect.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.connect.overload2 connect]``(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.connect.overload2 more...]]``
+
+
+[section:overload1 basic_socket::connect (1 of 2 overloads)]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.connect(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::connect (2 of 2 overloads)]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ asio::error_code ec;
+ socket.connect(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_socket::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.debug..debug..basic_socket]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_socket::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.do_not_route..do_not_route..basic_socket]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_socket::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.enable_connection_aborted..enable_connection_aborted..basic_socket]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_socket::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_socket.endpoint_type..endpoint_type..basic_socket]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_socket::executor_type]
+
+[indexterm2 asio.indexterm.basic_socket.executor_type..executor_type..basic_socket]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_socket::get_executor]
+
+[indexterm2 asio.indexterm.basic_socket.get_executor..get_executor..basic_socket]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_socket::get_io_context]
+
+[indexterm2 asio.indexterm.basic_socket.get_io_context..get_io_context..basic_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_socket::get_io_service]
+
+[indexterm2 asio.indexterm.basic_socket.get_io_service..get_io_service..basic_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_socket::get_option]
+
+[indexterm2 asio.indexterm.basic_socket.get_option..get_option..basic_socket]
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_socket.get_option.overload1 get_option]``(
+ GettableSocketOption & option) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_socket.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_socket::get_option (1 of 2 overloads)]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::get_option (2 of 2 overloads)]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ asio::error_code ec;
+ socket.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_socket::io_control]
+
+[indexterm2 asio.indexterm.basic_socket.io_control..io_control..basic_socket]
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_socket.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_socket.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_socket::io_control (1 of 2 overloads)]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::io_control (2 of 2 overloads)]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_socket::is_open]
+
+[indexterm2 asio.indexterm.basic_socket.is_open..is_open..basic_socket]
+Determine whether the socket is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_socket::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.keep_alive..keep_alive..basic_socket]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_socket::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.linger..linger..basic_socket]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:local_endpoint basic_socket::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_socket.local_endpoint..local_endpoint..basic_socket]
+Get the local endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_socket.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_socket.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_socket::local_endpoint (1 of 2 overloads)]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::local_endpoint (2 of 2 overloads)]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer basic_socket::lowest_layer]
+
+[indexterm2 asio.indexterm.basic_socket.lowest_layer..lowest_layer..basic_socket]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.basic_socket.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.basic_socket.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 basic_socket::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type basic_socket::lowest_layer_type]
+
+[indexterm2 asio.indexterm.basic_socket.lowest_layer_type..lowest_layer_type..basic_socket]
+A [link asio.reference.basic_socket `basic_socket`] is always the lowest layer.
+
+
+ typedef basic_socket< Protocol > lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections basic_socket::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.max_connections..max_connections..basic_socket]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_socket::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.max_listen_connections..max_listen_connections..basic_socket]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_socket::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.message_do_not_route..message_do_not_route..basic_socket]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_socket::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.message_end_of_record..message_end_of_record..basic_socket]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_socket::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.message_flags..message_flags..basic_socket]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_socket::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.message_out_of_band..message_out_of_band..basic_socket]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_socket::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.message_peek..message_peek..basic_socket]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_socket::native_handle]
+
+[indexterm2 asio.indexterm.basic_socket.native_handle..native_handle..basic_socket]
+Get the native socket representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the socket. This is intended to allow access to native socket functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_socket::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_socket.native_handle_type..native_handle_type..basic_socket]
+The native representation of a socket.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_socket::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_socket.native_non_blocking..native_non_blocking..basic_socket]
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool ``[link asio.reference.basic_socket.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void ``[link asio.reference.basic_socket.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_socket.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_socket::native_non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native socket. This mode has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying socket is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the socket object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native socket.
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::native_non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket::native_non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_socket::non_blocking]
+
+[indexterm2 asio.indexterm.basic_socket.non_blocking..non_blocking..basic_socket]
+Gets the non-blocking mode of the socket.
+
+
+ bool ``[link asio.reference.basic_socket.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void ``[link asio.reference.basic_socket.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_socket.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_socket::non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the socket.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket::non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_socket::open]
+
+[indexterm2 asio.indexterm.basic_socket.open..open..basic_socket]
+Open the socket using the specified protocol.
+
+
+ void ``[link asio.reference.basic_socket.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_socket.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.open.overload2 more...]]``
+
+
+[section:overload1 basic_socket::open (1 of 2 overloads)]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::open (2 of 2 overloads)]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ socket.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_socket::operator=]
+
+[indexterm2 asio.indexterm.basic_socket.operator_eq_..operator=..basic_socket]
+Move-assign a [link asio.reference.basic_socket `basic_socket`] from another.
+
+
+ basic_socket & ``[link asio.reference.basic_socket.operator_eq_.overload1 operator=]``(
+ basic_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_socket `basic_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_socket >::type & ``[link asio.reference.basic_socket.operator_eq_.overload2 operator=]``(
+ basic_socket< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_socket::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_socket `basic_socket`] from another.
+
+
+ basic_socket & operator=(
+ basic_socket && other);
+
+
+This assignment operator moves a socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket `basic_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_socket `basic_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_socket >::type & operator=(
+ basic_socket< Protocol1 > && other);
+
+
+This assignment operator moves a socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket `basic_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_socket::protocol_type]
+
+[indexterm2 asio.indexterm.basic_socket.protocol_type..protocol_type..basic_socket]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_buffer_size basic_socket::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.receive_buffer_size..receive_buffer_size..basic_socket]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_low_watermark basic_socket::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.receive_low_watermark..receive_low_watermark..basic_socket]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:remote_endpoint basic_socket::remote_endpoint]
+
+[indexterm2 asio.indexterm.basic_socket.remote_endpoint..remote_endpoint..basic_socket]
+Get the remote endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_socket.remote_endpoint.overload1 remote_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.remote_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_socket.remote_endpoint.overload2 remote_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket.remote_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_socket::remote_endpoint (1 of 2 overloads)]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint() const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::remote_endpoint (2 of 2 overloads)]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:reuse_address basic_socket::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.reuse_address..reuse_address..basic_socket]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_buffer_size basic_socket::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.send_buffer_size..send_buffer_size..basic_socket]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_socket::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.send_low_watermark..send_low_watermark..basic_socket]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:set_option basic_socket::set_option]
+
+[indexterm2 asio.indexterm.basic_socket.set_option..set_option..basic_socket]
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_socket.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_socket.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_socket::set_option (1 of 2 overloads)]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::set_option (2 of 2 overloads)]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ asio::error_code ec;
+ socket.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown basic_socket::shutdown]
+
+[indexterm2 asio.indexterm.basic_socket.shutdown..shutdown..basic_socket]
+Disable sends or receives on the socket.
+
+
+ void ``[link asio.reference.basic_socket.shutdown.overload1 shutdown]``(
+ shutdown_type what);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.shutdown.overload2 shutdown]``(
+ shutdown_type what,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.shutdown.overload2 more...]]``
+
+
+[section:overload1 basic_socket::shutdown (1 of 2 overloads)]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::shutdown (2 of 2 overloads)]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what,
+ asio::error_code & ec);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_socket::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.shutdown_type..shutdown_type..basic_socket]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_socket.shutdown_type.shutdown_receive..shutdown_receive..basic_socket]
+[indexterm2 asio.indexterm.basic_socket.shutdown_type.shutdown_send..shutdown_send..basic_socket]
+[indexterm2 asio.indexterm.basic_socket.shutdown_type.shutdown_both..shutdown_both..basic_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_socket::wait]
+
+[indexterm2 asio.indexterm.basic_socket.wait..wait..basic_socket]
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_socket.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket.wait.overload2 more...]]``
+
+
+[section:overload1 basic_socket::wait (1 of 2 overloads)]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.wait(asio::ip::tcp::socket::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket::wait (2 of 2 overloads)]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.wait(asio::ip::tcp::socket::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_socket::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket.wait_type..wait_type..basic_socket]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_socket.wait_type.wait_read..wait_read..basic_socket]
+[indexterm2 asio.indexterm.basic_socket.wait_type.wait_write..wait_write..basic_socket]
+[indexterm2 asio.indexterm.basic_socket.wait_type.wait_error..wait_error..basic_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_basic_socket basic_socket::~basic_socket]
+
+[indexterm2 asio.indexterm.basic_socket._basic_socket..~basic_socket..basic_socket]
+Protected destructor to prevent deletion through this type.
+
+
+ ~basic_socket();
+
+
+This function destroys the socket, cancelling any outstanding asynchronous operations associated with the socket as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_socket_acceptor basic_socket_acceptor]
+
+
+Provides the ability to accept new connections.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_socket_acceptor :
+ public socket_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.native_handle_type [*native_handle_type]]]
+ [The native representation of an acceptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.accept [*accept]]]
+ [Accept a new connection.
+
+ Accept a new connection and obtain the endpoint of the peer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.assign [*assign]]]
+ [Assigns an existing native acceptor to the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_accept [*async_accept]]]
+ [Start an asynchronous accept. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.basic_socket_acceptor [*basic_socket_acceptor]]]
+ [Construct an acceptor without opening it.
+
+ Construct an open acceptor.
+
+ Construct an acceptor opened on the given endpoint.
+
+ Construct a basic_socket_acceptor on an existing native acceptor.
+
+ Move-construct a basic_socket_acceptor from another.
+
+ Move-construct a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.bind [*bind]]]
+ [Bind the acceptor to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.close [*close]]]
+ [Close the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_option [*get_option]]]
+ [Get an option from the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.io_control [*io_control]]]
+ [Perform an IO control command on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.is_open [*is_open]]]
+ [Determine whether the acceptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.listen [*listen]]]
+ [Place the acceptor into the state where it will listen for new connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_handle [*native_handle]]]
+ [Get the native acceptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native acceptor implementation.
+
+ Sets the non-blocking mode of the native acceptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the acceptor.
+
+ Sets the non-blocking mode of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.open [*open]]]
+ [Open the acceptor using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_acceptor from another.
+
+ Move-assign a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.set_option [*set_option]]]
+ [Set an option on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.wait [*wait]]]
+ [Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor._basic_socket_acceptor [*~basic_socket_acceptor]]]
+ [Destroys the acceptor. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] class template is used for accepting new socket connections.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Example]
+
+Opening a socket acceptor with the SO\_REUSEADDR option enabled:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
+ acceptor.open(endpoint.protocol());
+ acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor.bind(endpoint);
+ acceptor.listen();
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:accept basic_socket_acceptor::accept]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.accept..accept..basic_socket_acceptor]
+Accept a new connection.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ void ``[link asio.reference.basic_socket_acceptor.accept.overload1 accept]``(
+ basic_socket< Protocol1 > & peer,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ void ``[link asio.reference.basic_socket_acceptor.accept.overload2 accept]``(
+ basic_socket< Protocol1 > & peer,
+ asio::error_code & ec,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload2 more...]]``
+
+
+Accept a new connection and obtain the endpoint of the peer.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.accept.overload3 accept]``(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload3 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.accept.overload4 accept]``(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload4 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload5 accept]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload5 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload6 accept]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload6 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload7 accept]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload7 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload8 accept]``(
+ asio::io_context & io_context,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload8 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload9 accept]``(
+ endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload9 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload10 accept]``(
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload10 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload11 accept]``(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload11 more...]]``
+
+ Protocol::socket ``[link asio.reference.basic_socket_acceptor.accept.overload12 accept]``(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.accept.overload12 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::accept (1 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ void accept(
+ basic_socket< Protocol1 > & peer,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+
+
+This function is used to accept a new connection from a peer into the given socket. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(io_context);
+ acceptor.accept(socket);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::accept (2 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ void accept(
+ basic_socket< Protocol1 > & peer,
+ asio::error_code & ec,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+
+
+This function is used to accept a new connection from a peer into the given socket. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ acceptor.accept(socket, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_acceptor::accept (3 of 12 overloads)]
+
+
+Accept a new connection and obtain the endpoint of the peer.
+
+
+ void accept(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint);
+
+
+This function is used to accept a new connection from a peer into the given socket, and additionally provide the endpoint of the remote peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted.]]
+
+[[peer_endpoint][An endpoint object which will receive the endpoint of the remote peer.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint;
+ acceptor.accept(socket, endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_socket_acceptor::accept (4 of 12 overloads)]
+
+
+Accept a new connection and obtain the endpoint of the peer.
+
+
+ void accept(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to accept a new connection from a peer into the given socket, and additionally provide the endpoint of the remote peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted.]]
+
+[[peer_endpoint][An endpoint object which will receive the endpoint of the remote peer.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint;
+ asio::error_code ec;
+ acceptor.accept(socket, endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_socket_acceptor::accept (5 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept();
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Return Value]
+
+A socket object representing the newly accepted connection.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(acceptor.accept());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_socket_acceptor::accept (6 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ asio::error_code & ec);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+On success, a socket object representing the newly accepted connection. On error, a socket object where `is_open()` is false.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(acceptor.accept(ec));
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 basic_socket_acceptor::accept (7 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ asio::io_context & io_context);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+]
+
+
+[heading Return Value]
+
+A socket object representing the newly accepted connection.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(acceptor.accept());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 basic_socket_acceptor::accept (8 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ asio::io_context & io_context,
+ asio::error_code & ec);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+On success, a socket object representing the newly accepted connection. On error, a socket object where `is_open()` is false.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 basic_socket_acceptor::accept (9 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ endpoint_type & peer_endpoint);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written.]]
+
+]
+
+
+[heading Return Value]
+
+A socket object representing the newly accepted connection.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ asio::ip::tcp::socket socket(acceptor.accept(endpoint));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 basic_socket_acceptor::accept (10 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+On success, a socket object representing the newly accepted connection. On error, a socket object where `is_open()` is false.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 basic_socket_acceptor::accept (11 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written.]]
+
+]
+
+
+[heading Return Value]
+
+A socket object representing the newly accepted connection.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ asio::ip::tcp::socket socket(
+ acceptor.accept(io_context2, endpoint));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 basic_socket_acceptor::accept (12 of 12 overloads)]
+
+
+Accept a new connection.
+
+
+ Protocol::socket accept(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to accept a new connection from a peer. The function call will block until a new connection has been accepted successfully or an error occurs.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+On success, a socket object representing the newly accepted connection. On error, a socket object where `is_open()` is false.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ asio::ip::tcp::socket socket(
+ acceptor.accept(io_context2, endpoint, ec));
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:assign basic_socket_acceptor::assign]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.assign..assign..basic_socket_acceptor]
+Assigns an existing native acceptor to the acceptor.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.assign.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::assign (1 of 2 overloads)]
+
+
+Assigns an existing native acceptor to the acceptor.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::assign (2 of 2 overloads)]
+
+
+Assigns an existing native acceptor to the acceptor.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_accept basic_socket_acceptor::async_accept]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.async_accept..async_accept..basic_socket_acceptor]
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``,
+ typename ``[link asio.reference.AcceptHandler AcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload1 async_accept]``(
+ basic_socket< Protocol1 > & peer,
+ AcceptHandler && handler,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.AcceptHandler AcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload2 async_accept]``(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint,
+ AcceptHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload3 async_accept]``(
+ MoveAcceptHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload4 async_accept]``(
+ asio::io_context & io_context,
+ MoveAcceptHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload5 async_accept]``(
+ endpoint_type & peer_endpoint,
+ MoveAcceptHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_socket_acceptor.async_accept.overload6 async_accept]``(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint,
+ MoveAcceptHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.async_accept.overload6 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::async_accept (1 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``,
+ typename ``[link asio.reference.AcceptHandler AcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ basic_socket< Protocol1 > & peer,
+ AcceptHandler && handler,
+ typename enable_if< is_convertible< Protocol, Protocol1 >::value >::type * = 0);
+
+
+This function is used to asynchronously accept a new connection into a socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted. Ownership of the peer object is retained by the caller, which must guarantee that it is valid until the handler is called.]]
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void accept_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Accept succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::socket socket(io_context);
+ acceptor.async_accept(socket, accept_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::async_accept (2 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.AcceptHandler AcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ basic_socket< protocol_type > & peer,
+ endpoint_type & peer_endpoint,
+ AcceptHandler && handler);
+
+
+This function is used to asynchronously accept a new connection into a socket, and additionally obtain the endpoint of the remote peer. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer][The socket into which the new connection will be accepted. Ownership of the peer object is retained by the caller, which must guarantee that it is valid until the handler is called.]]
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written. Ownership of the peer\_endpoint object is retained by the caller, which must guarantee that it is valid until the handler is called.]]
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_acceptor::async_accept (3 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ MoveAcceptHandler && handler);
+
+
+This function is used to asynchronously accept a new connection. The function call always returns immediately.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ typename Protocol::socket peer // On success, the newly accepted socket.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void accept_handler(const asio::error_code& error,
+ asio::ip::tcp::socket peer)
+ {
+ if (!error)
+ {
+ // Accept succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ acceptor.async_accept(accept_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_socket_acceptor::async_accept (4 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ asio::io_context & io_context,
+ MoveAcceptHandler && handler);
+
+
+This function is used to asynchronously accept a new connection. The function call always returns immediately.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ typename Protocol::socket peer // On success, the newly accepted socket.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void accept_handler(const asio::error_code& error,
+ asio::ip::tcp::socket peer)
+ {
+ if (!error)
+ {
+ // Accept succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ acceptor.async_accept(io_context2, accept_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_socket_acceptor::async_accept (5 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ endpoint_type & peer_endpoint,
+ MoveAcceptHandler && handler);
+
+
+This function is used to asynchronously accept a new connection. The function call always returns immediately.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written. Ownership of the peer\_endpoint object is retained by the caller, which must guarantee that it is valid until the handler is called.]]
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ typename Protocol::socket peer // On success, the newly accepted socket.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void accept_handler(const asio::error_code& error,
+ asio::ip::tcp::socket peer)
+ {
+ if (!error)
+ {
+ // Accept succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ acceptor.async_accept(endpoint, accept_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_socket_acceptor::async_accept (6 of 6 overloads)]
+
+
+Start an asynchronous accept.
+
+
+ template<
+ typename ``[link asio.reference.MoveAcceptHandler MoveAcceptHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_accept(
+ asio::io_context & io_context,
+ endpoint_type & peer_endpoint,
+ MoveAcceptHandler && handler);
+
+
+This function is used to asynchronously accept a new connection. The function call always returns immediately.
+
+This overload requires that the Protocol template parameter satisfy the AcceptableProtocol type requirements.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object to be used for the newly accepted socket.]]
+
+[[peer_endpoint][An endpoint object into which the endpoint of the remote peer will be written. Ownership of the peer\_endpoint object is retained by the caller, which must guarantee that it is valid until the handler is called.]]
+
+[[handler][The handler to be called when the accept operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ typename Protocol::socket peer // On success, the newly accepted socket.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void accept_handler(const asio::error_code& error,
+ asio::ip::tcp::socket peer)
+ {
+ if (!error)
+ {
+ // Accept succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint;
+ acceptor.async_accept(io_context2, endpoint, accept_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait basic_socket_acceptor::async_wait]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.async_wait..async_wait..basic_socket_acceptor]
+Asynchronously wait for the acceptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for an acceptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired acceptor state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ acceptor.async_wait(
+ asio::ip::tcp::acceptor::wait_read,
+ wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+[section:basic_socket_acceptor basic_socket_acceptor::basic_socket_acceptor]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.basic_socket_acceptor..basic_socket_acceptor..basic_socket_acceptor]
+Construct an acceptor without opening it.
+
+
+ explicit ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload1 basic_socket_acceptor]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload1 more...]]``
+
+
+Construct an open acceptor.
+
+
+ ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload2 basic_socket_acceptor]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload2 more...]]``
+
+
+Construct an acceptor opened on the given endpoint.
+
+
+ ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload3 basic_socket_acceptor]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint,
+ bool reuse_addr = true);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] on an existing native acceptor.
+
+
+ ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload4 basic_socket_acceptor]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from another.
+
+
+ ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload5 basic_socket_acceptor]``(
+ basic_socket_acceptor && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from an acceptor of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload6 basic_socket_acceptor]``(
+ basic_socket_acceptor< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.basic_socket_acceptor.overload6 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::basic_socket_acceptor (1 of 6 overloads)]
+
+
+Construct an acceptor without opening it.
+
+
+ basic_socket_acceptor(
+ asio::io_context & io_context);
+
+
+This constructor creates an acceptor without opening it to listen for new connections. The `open()` function must be called before the acceptor can accept new socket connections.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the acceptor will use to dispatch handlers for any asynchronous operations performed on the acceptor. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::basic_socket_acceptor (2 of 6 overloads)]
+
+
+Construct an open acceptor.
+
+
+ basic_socket_acceptor(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates an acceptor and automatically opens it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the acceptor will use to dispatch handlers for any asynchronous operations performed on the acceptor.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_acceptor::basic_socket_acceptor (3 of 6 overloads)]
+
+
+Construct an acceptor opened on the given endpoint.
+
+
+ basic_socket_acceptor(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint,
+ bool reuse_addr = true);
+
+
+This constructor creates an acceptor and automatically opens it to listen for new connections on the specified endpoint.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the acceptor will use to dispatch handlers for any asynchronous operations performed on the acceptor.]]
+
+[[endpoint][An endpoint on the local machine on which the acceptor will listen for new connections.]]
+
+[[reuse_addr][Whether the constructor should set the socket option `socket_base::reuse_address`.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This constructor is equivalent to the following code:
+
+ basic_socket_acceptor<Protocol> acceptor(io_context);
+ acceptor.open(endpoint.protocol());
+ if (reuse_addr)
+ acceptor.set_option(socket_base::reuse_address(true));
+ acceptor.bind(endpoint);
+ acceptor.listen(listen_backlog);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_socket_acceptor::basic_socket_acceptor (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] on an existing native acceptor.
+
+
+ basic_socket_acceptor(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_acceptor);
+
+
+This constructor creates an acceptor object to hold an existing native acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the acceptor will use to dispatch handlers for any asynchronous operations performed on the acceptor.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_acceptor][A native acceptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_socket_acceptor::basic_socket_acceptor (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from another.
+
+
+ basic_socket_acceptor(
+ basic_socket_acceptor && other);
+
+
+This constructor moves an acceptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket_acceptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_socket_acceptor::basic_socket_acceptor (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from an acceptor of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_socket_acceptor(
+ basic_socket_acceptor< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves an acceptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_socket_acceptor::bind]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.bind..bind..basic_socket_acceptor]
+Bind the acceptor to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.bind.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::bind (1 of 2 overloads)]
+
+
+Bind the acceptor to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket acceptor to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket acceptor will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
+ acceptor.open(endpoint.protocol());
+ acceptor.bind(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::bind (2 of 2 overloads)]
+
+
+Bind the acceptor to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket acceptor to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket acceptor will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
+ acceptor.open(endpoint.protocol());
+ asio::error_code ec;
+ acceptor.bind(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_socket_acceptor::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.broadcast..broadcast..basic_socket_acceptor]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_socket_acceptor::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.bytes_readable..bytes_readable..basic_socket_acceptor]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_socket_acceptor::cancel]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.cancel..cancel..basic_socket_acceptor]
+Cancel all asynchronous operations associated with the acceptor.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the acceptor.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the acceptor.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_socket_acceptor::close]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.close..close..basic_socket_acceptor]
+Close the acceptor.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.close.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::close (1 of 2 overloads)]
+
+
+Close the acceptor.
+
+
+ void close();
+
+
+This function is used to close the acceptor. Any asynchronous accept operations will be cancelled immediately.
+
+A subsequent call to `open()` is required before the acceptor can again be used to again perform socket accept operations.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::close (2 of 2 overloads)]
+
+
+Close the acceptor.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the acceptor. Any asynchronous accept operations will be cancelled immediately.
+
+A subsequent call to `open()` is required before the acceptor can again be used to again perform socket accept operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::error_code ec;
+ acceptor.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_socket_acceptor::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.debug..debug..basic_socket_acceptor]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_socket_acceptor::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.do_not_route..do_not_route..basic_socket_acceptor]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_socket_acceptor::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.enable_connection_aborted..enable_connection_aborted..basic_socket_acceptor]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_socket_acceptor::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.endpoint_type..endpoint_type..basic_socket_acceptor]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_socket_acceptor::executor_type]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.executor_type..executor_type..basic_socket_acceptor]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_socket_acceptor::get_executor]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.get_executor..get_executor..basic_socket_acceptor]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_socket_acceptor::get_io_context]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.get_io_context..get_io_context..basic_socket_acceptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_socket_acceptor::get_io_service]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.get_io_service..get_io_service..basic_socket_acceptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_socket_acceptor::get_option]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.get_option..get_option..basic_socket_acceptor]
+Get an option from the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_socket_acceptor.get_option.overload1 get_option]``(
+ GettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_socket_acceptor.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::get_option (1 of 2 overloads)]
+
+
+Get an option from the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option);
+
+
+This function is used to get the current value of an option on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the acceptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_REUSEADDR option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::get_option (2 of 2 overloads)]
+
+
+Get an option from the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to get the current value of an option on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the acceptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_REUSEADDR option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::reuse_address option;
+ asio::error_code ec;
+ acceptor.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_socket_acceptor::io_control]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.io_control..io_control..basic_socket_acceptor]
+Perform an IO control command on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_socket_acceptor.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_socket_acceptor.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::io_control (1 of 2 overloads)]
+
+
+Perform an IO control command on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the acceptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::non_blocking_io command(true);
+ socket.io_control(command);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::io_control (2 of 2 overloads)]
+
+
+Perform an IO control command on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the acceptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::non_blocking_io command(true);
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_socket_acceptor::is_open]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.is_open..is_open..basic_socket_acceptor]
+Determine whether the acceptor is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_socket_acceptor::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.keep_alive..keep_alive..basic_socket_acceptor]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_socket_acceptor::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.linger..linger..basic_socket_acceptor]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:listen basic_socket_acceptor::listen]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.listen..listen..basic_socket_acceptor]
+Place the acceptor into the state where it will listen for new connections.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.listen.overload1 listen]``(
+ int backlog = socket_base::max_listen_connections);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.listen.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.listen.overload2 listen]``(
+ int backlog,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.listen.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::listen (1 of 2 overloads)]
+
+
+Place the acceptor into the state where it will listen for new connections.
+
+
+ void listen(
+ int backlog = socket_base::max_listen_connections);
+
+
+This function puts the socket acceptor into the state where it may accept new connections.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[backlog][The maximum length of the queue of pending connections.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::listen (2 of 2 overloads)]
+
+
+Place the acceptor into the state where it will listen for new connections.
+
+
+ void listen(
+ int backlog,
+ asio::error_code & ec);
+
+
+This function puts the socket acceptor into the state where it may accept new connections.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[backlog][The maximum length of the queue of pending connections.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::error_code ec;
+ acceptor.listen(asio::socket_base::max_listen_connections, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:local_endpoint basic_socket_acceptor::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.local_endpoint..local_endpoint..basic_socket_acceptor]
+Get the local endpoint of the acceptor.
+
+
+ endpoint_type ``[link asio.reference.basic_socket_acceptor.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_socket_acceptor.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::local_endpoint (1 of 2 overloads)]
+
+
+Get the local endpoint of the acceptor.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the acceptor.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the acceptor.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::local_endpoint (2 of 2 overloads)]
+
+
+Get the local endpoint of the acceptor.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the acceptor. Returns a default-constructed endpoint object if an error occurred and the error handler did not throw an exception.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:max_connections basic_socket_acceptor::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.max_connections..max_connections..basic_socket_acceptor]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_socket_acceptor::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.max_listen_connections..max_listen_connections..basic_socket_acceptor]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_socket_acceptor::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.message_do_not_route..message_do_not_route..basic_socket_acceptor]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_socket_acceptor::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.message_end_of_record..message_end_of_record..basic_socket_acceptor]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_socket_acceptor::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.message_flags..message_flags..basic_socket_acceptor]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_socket_acceptor::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.message_out_of_band..message_out_of_band..basic_socket_acceptor]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_socket_acceptor::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.message_peek..message_peek..basic_socket_acceptor]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_socket_acceptor::native_handle]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.native_handle..native_handle..basic_socket_acceptor]
+Get the native acceptor representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the acceptor. This is intended to allow access to native acceptor functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_socket_acceptor::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.native_handle_type..native_handle_type..basic_socket_acceptor]
+The native representation of an acceptor.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_socket_acceptor::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.native_non_blocking..native_non_blocking..basic_socket_acceptor]
+Gets the non-blocking mode of the native acceptor implementation.
+
+
+ bool ``[link asio.reference.basic_socket_acceptor.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native acceptor implementation.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::native_non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the native acceptor implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native acceptor. This mode has no effect on the behaviour of the acceptor object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying acceptor is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the acceptor object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native acceptor.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::native_non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native acceptor implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native acceptor. It has no effect on the behaviour of the acceptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying acceptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_acceptor::native_non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native acceptor implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native acceptor. It has no effect on the behaviour of the acceptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying acceptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_socket_acceptor::non_blocking]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.non_blocking..non_blocking..basic_socket_acceptor]
+Gets the non-blocking mode of the acceptor.
+
+
+ bool ``[link asio.reference.basic_socket_acceptor.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the acceptor.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the acceptor.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the acceptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the acceptor.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the acceptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_acceptor::non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the acceptor.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the acceptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_socket_acceptor::open]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.open..open..basic_socket_acceptor]
+Open the acceptor using the specified protocol.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.open.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::open (1 of 2 overloads)]
+
+
+Open the acceptor using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket acceptor so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ acceptor.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::open (2 of 2 overloads)]
+
+
+Open the acceptor using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket acceptor so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::error_code ec;
+ acceptor.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_socket_acceptor::operator=]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.operator_eq_..operator=..basic_socket_acceptor]
+Move-assign a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from another.
+
+
+ basic_socket_acceptor & ``[link asio.reference.basic_socket_acceptor.operator_eq_.overload1 operator=]``(
+ basic_socket_acceptor && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from an acceptor of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_socket_acceptor >::type & ``[link asio.reference.basic_socket_acceptor.operator_eq_.overload2 operator=]``(
+ basic_socket_acceptor< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from another.
+
+
+ basic_socket_acceptor & operator=(
+ basic_socket_acceptor && other);
+
+
+This assignment operator moves an acceptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket_acceptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] from an acceptor of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_socket_acceptor >::type & operator=(
+ basic_socket_acceptor< Protocol1 > && other);
+
+
+This assignment operator moves an acceptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_socket_acceptor::protocol_type]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.protocol_type..protocol_type..basic_socket_acceptor]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_buffer_size basic_socket_acceptor::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.receive_buffer_size..receive_buffer_size..basic_socket_acceptor]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_low_watermark basic_socket_acceptor::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.receive_low_watermark..receive_low_watermark..basic_socket_acceptor]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reuse_address basic_socket_acceptor::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.reuse_address..reuse_address..basic_socket_acceptor]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_buffer_size basic_socket_acceptor::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.send_buffer_size..send_buffer_size..basic_socket_acceptor]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_socket_acceptor::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.send_low_watermark..send_low_watermark..basic_socket_acceptor]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_acceptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:set_option basic_socket_acceptor::set_option]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.set_option..set_option..basic_socket_acceptor]
+Set an option on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_socket_acceptor.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_socket_acceptor.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::set_option (1 of 2 overloads)]
+
+
+Set an option on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the acceptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the SOL\_SOCKET/SO\_REUSEADDR option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::set_option (2 of 2 overloads)]
+
+
+Set an option on the acceptor.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the acceptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the acceptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the SOL\_SOCKET/SO\_REUSEADDR option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::ip::tcp::acceptor::reuse_address option(true);
+ asio::error_code ec;
+ acceptor.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_socket_acceptor::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.shutdown_type..shutdown_type..basic_socket_acceptor]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.shutdown_type.shutdown_receive..shutdown_receive..basic_socket_acceptor]
+[indexterm2 asio.indexterm.basic_socket_acceptor.shutdown_type.shutdown_send..shutdown_send..basic_socket_acceptor]
+[indexterm2 asio.indexterm.basic_socket_acceptor.shutdown_type.shutdown_both..shutdown_both..basic_socket_acceptor]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_socket_acceptor::wait]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.wait..wait..basic_socket_acceptor]
+Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_socket_acceptor.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_socket_acceptor.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_acceptor.wait.overload2 more...]]``
+
+
+[section:overload1 basic_socket_acceptor::wait (1 of 2 overloads)]
+
+
+Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for an acceptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired acceptor state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for an acceptor to become readable.
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ acceptor.wait(asio::ip::tcp::acceptor::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_acceptor::wait (2 of 2 overloads)]
+
+
+Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for an acceptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired acceptor state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for an acceptor to become readable.
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::error_code ec;
+ acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_socket_acceptor::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.wait_type..wait_type..basic_socket_acceptor]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_socket_acceptor.wait_type.wait_read..wait_read..basic_socket_acceptor]
+[indexterm2 asio.indexterm.basic_socket_acceptor.wait_type.wait_write..wait_write..basic_socket_acceptor]
+[indexterm2 asio.indexterm.basic_socket_acceptor.wait_type.wait_error..wait_error..basic_socket_acceptor]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_basic_socket_acceptor basic_socket_acceptor::~basic_socket_acceptor]
+
+[indexterm2 asio.indexterm.basic_socket_acceptor._basic_socket_acceptor..~basic_socket_acceptor..basic_socket_acceptor]
+Destroys the acceptor.
+
+
+ ~basic_socket_acceptor();
+
+
+This function destroys the acceptor, cancelling any outstanding asynchronous operations associated with the acceptor as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_socket_iostream basic_socket_iostream]
+
+
+Iostream interface for a socket.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Clock = chrono::steady_clock,
+ typename ``[link asio.reference.WaitTraits WaitTraits]`` = wait_traits<Clock>>
+ class basic_socket_iostream
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration [*duration]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration_type [*duration_type]]]
+ [(Deprecated: Use duration.) The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_point [*time_point]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_type [*time_type]]]
+ [(Deprecated: Use time_point.) The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_iostream.basic_socket_iostream [*basic_socket_iostream]]]
+ [Construct a basic_socket_iostream without establishing a connection.
+
+ Construct a basic_socket_iostream from the supplied socket.
+
+ Move-construct a basic_socket_iostream from another.
+
+ Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.close [*close]]]
+ [Close the connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.connect [*connect]]]
+ [Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.error [*error]]]
+ [Get the last error associated with the stream. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_after [*expires_after]]]
+ [Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time as an absolute time.
+
+ Set the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expiry [*expiry]]]
+ [Get the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_iostream from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.rdbuf [*rdbuf]]]
+ [Return a pointer to the underlying streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.socket [*socket]]]
+ [Get a reference to the underlying socket. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_socket_iostream basic_socket_iostream::basic_socket_iostream]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.basic_socket_iostream..basic_socket_iostream..basic_socket_iostream]
+Construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] without establishing a connection.
+
+
+ ``[link asio.reference.basic_socket_iostream.basic_socket_iostream.overload1 basic_socket_iostream]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.basic_socket_iostream.overload1 more...]]``
+
+
+Construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] from the supplied socket.
+
+
+ explicit ``[link asio.reference.basic_socket_iostream.basic_socket_iostream.overload2 basic_socket_iostream]``(
+ basic_stream_socket< protocol_type > s);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.basic_socket_iostream.overload2 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] from another.
+
+
+ ``[link asio.reference.basic_socket_iostream.basic_socket_iostream.overload3 basic_socket_iostream]``(
+ basic_socket_iostream && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.basic_socket_iostream.overload3 more...]]``
+
+
+Establish a connection to an endpoint corresponding to a resolver query.
+
+
+ template<
+ typename T1,
+ ... ,
+ typename TN>
+ explicit ``[link asio.reference.basic_socket_iostream.basic_socket_iostream.overload4 basic_socket_iostream]``(
+ T1 t1,
+ ... ,
+ TN tn);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.basic_socket_iostream.overload4 more...]]``
+
+
+[section:overload1 basic_socket_iostream::basic_socket_iostream (1 of 4 overloads)]
+
+
+Construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] without establishing a connection.
+
+
+ basic_socket_iostream();
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_iostream::basic_socket_iostream (2 of 4 overloads)]
+
+
+Construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] from the supplied socket.
+
+
+ basic_socket_iostream(
+ basic_stream_socket< protocol_type > s);
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_iostream::basic_socket_iostream (3 of 4 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] from another.
+
+
+ basic_socket_iostream(
+ basic_socket_iostream && other);
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_socket_iostream::basic_socket_iostream (4 of 4 overloads)]
+
+
+Establish a connection to an endpoint corresponding to a resolver query.
+
+
+ template<
+ typename T1,
+ ... ,
+ typename TN>
+ basic_socket_iostream(
+ T1 t1,
+ ... ,
+ TN tn);
+
+
+This constructor automatically establishes a connection based on the supplied resolver query parameters. The arguments are used to construct a resolver query object.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:clock_type basic_socket_iostream::clock_type]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.clock_type..clock_type..basic_socket_iostream]
+The clock type.
+
+
+ typedef Clock clock_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:close basic_socket_iostream::close]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.close..close..basic_socket_iostream]
+Close the connection.
+
+
+ void close();
+
+
+
+[endsect]
+
+
+
+[section:connect basic_socket_iostream::connect]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.connect..connect..basic_socket_iostream]
+Establish a connection to an endpoint corresponding to a resolver query.
+
+
+ template<
+ typename T1,
+ ... ,
+ typename TN>
+ void connect(
+ T1 t1,
+ ... ,
+ TN tn);
+
+
+This function automatically establishes a connection based on the supplied resolver query parameters. The arguments are used to construct a resolver query object.
+
+
+[endsect]
+
+
+
+[section:duration basic_socket_iostream::duration]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.duration..duration..basic_socket_iostream]
+The duration type.
+
+
+ typedef WaitTraits::duration duration;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:duration_type basic_socket_iostream::duration_type]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.duration_type..duration_type..basic_socket_iostream]
+(Deprecated: Use duration.) The duration type.
+
+
+ typedef WaitTraits::duration_type duration_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_socket_iostream::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.endpoint_type..endpoint_type..basic_socket_iostream]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error basic_socket_iostream::error]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.error..error..basic_socket_iostream]
+Get the last error associated with the stream.
+
+
+ const asio::error_code & error() const;
+
+
+
+[heading Return Value]
+
+An `error_code` corresponding to the last error from the stream.
+
+
+[heading Example]
+
+To print the error associated with a failure to establish a connection:
+
+ tcp::iostream s("www.boost.org", "http");
+ if (!s)
+ {
+ std::cout << "Error: " << s.error().message() << std::endl;
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:expires_after basic_socket_iostream::expires_after]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.expires_after..expires_after..basic_socket_iostream]
+Set the stream's expiry time relative to now.
+
+
+ void expires_after(
+ const duration & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:expires_at basic_socket_iostream::expires_at]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.expires_at..expires_at..basic_socket_iostream]
+(Deprecated: Use `expiry()`.) Get the stream's expiry time as an absolute time.
+
+
+ time_point ``[link asio.reference.basic_socket_iostream.expires_at.overload1 expires_at]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.expires_at.overload1 more...]]``
+
+
+Set the stream's expiry time as an absolute time.
+
+
+ void ``[link asio.reference.basic_socket_iostream.expires_at.overload2 expires_at]``(
+ const time_point & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.expires_at.overload2 more...]]``
+
+
+[section:overload1 basic_socket_iostream::expires_at (1 of 2 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the stream's expiry time as an absolute time.
+
+
+ time_point expires_at() const;
+
+
+
+[heading Return Value]
+
+An absolute time value representing the stream's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_iostream::expires_at (2 of 2 overloads)]
+
+
+Set the stream's expiry time as an absolute time.
+
+
+ void expires_at(
+ const time_point & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the stream. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:expires_from_now basic_socket_iostream::expires_from_now]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.expires_from_now..expires_from_now..basic_socket_iostream]
+(Deprecated: Use `expiry()`.) Get the stream's expiry time relative to now.
+
+
+ duration ``[link asio.reference.basic_socket_iostream.expires_from_now.overload1 expires_from_now]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.expires_from_now.overload1 more...]]``
+
+
+(Deprecated: Use `expires_after()`.) Set the stream's expiry time relative to now.
+
+
+ void ``[link asio.reference.basic_socket_iostream.expires_from_now.overload2 expires_from_now]``(
+ const duration & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_iostream.expires_from_now.overload2 more...]]``
+
+
+[section:overload1 basic_socket_iostream::expires_from_now (1 of 2 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the stream's expiry time relative to now.
+
+
+ duration expires_from_now() const;
+
+
+
+[heading Return Value]
+
+A relative time value representing the stream's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_iostream::expires_from_now (2 of 2 overloads)]
+
+
+(Deprecated: Use `expires_after()`.) Set the stream's expiry time relative to now.
+
+
+ void expires_from_now(
+ const duration & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:expiry basic_socket_iostream::expiry]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.expiry..expiry..basic_socket_iostream]
+Get the stream's expiry time as an absolute time.
+
+
+ time_point expiry() const;
+
+
+
+[heading Return Value]
+
+An absolute time value representing the stream's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ basic_socket_iostream::operator=]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.operator_eq_..operator=..basic_socket_iostream]
+Move-assign a [link asio.reference.basic_socket_iostream `basic_socket_iostream`] from another.
+
+
+ basic_socket_iostream & operator=(
+ basic_socket_iostream && other);
+
+
+
+[endsect]
+
+
+
+[section:protocol_type basic_socket_iostream::protocol_type]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.protocol_type..protocol_type..basic_socket_iostream]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:rdbuf basic_socket_iostream::rdbuf]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.rdbuf..rdbuf..basic_socket_iostream]
+Return a pointer to the underlying streambuf.
+
+
+ basic_socket_streambuf< Protocol, Clock, WaitTraits > * rdbuf() const;
+
+
+
+[endsect]
+
+
+
+[section:socket basic_socket_iostream::socket]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.socket..socket..basic_socket_iostream]
+Get a reference to the underlying socket.
+
+
+ basic_socket< Protocol > & socket();
+
+
+
+[endsect]
+
+
+
+[section:time_point basic_socket_iostream::time_point]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.time_point..time_point..basic_socket_iostream]
+The time type.
+
+
+ typedef WaitTraits::time_point time_point;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:time_type basic_socket_iostream::time_type]
+
+[indexterm2 asio.indexterm.basic_socket_iostream.time_type..time_type..basic_socket_iostream]
+(Deprecated: Use time\_point.) The time type.
+
+
+ typedef WaitTraits::time_type time_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_iostream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_socket_streambuf basic_socket_streambuf]
+
+
+Iostream streambuf for a socket.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Clock = chrono::steady_clock,
+ typename ``[link asio.reference.WaitTraits WaitTraits]`` = wait_traits<Clock>>
+ class basic_socket_streambuf :
+ basic_socket< Protocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.duration [*duration]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.duration_type [*duration_type]]]
+ [(Deprecated: Use duration.) The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.time_point [*time_point]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_streambuf.time_type [*time_type]]]
+ [(Deprecated: Use time_point.) The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.basic_socket_streambuf [*basic_socket_streambuf]]]
+ [Construct a basic_socket_streambuf without establishing a connection.
+
+ Construct a basic_socket_streambuf from the supplied socket.
+
+ Move-construct a basic_socket_streambuf from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.close [*close]]]
+ [Close the connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.connect [*connect]]]
+ [Establish a connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.error [*error]]]
+ [Get the last error associated with the stream buffer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.expires_after [*expires_after]]]
+ [Set the stream buffer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the stream buffer's expiry time as an absolute time.
+
+ Set the stream buffer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the stream buffer's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the stream buffer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.expiry [*expiry]]]
+ [Get the stream buffer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_streambuf from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.puberror [*puberror]]]
+ [(Deprecated: Use error().) Get the last error associated with the stream buffer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.socket [*socket]]]
+ [Get a reference to the underlying socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf._basic_socket_streambuf [*~basic_socket_streambuf]]]
+ [Destructor flushes buffered data. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.overflow [*overflow]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.setbuf [*setbuf]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.sync [*sync]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_socket_streambuf.underflow [*underflow]]]
+ []
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_socket_streambuf basic_socket_streambuf::basic_socket_streambuf]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.basic_socket_streambuf..basic_socket_streambuf..basic_socket_streambuf]
+Construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] without establishing a connection.
+
+
+ ``[link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload1 basic_socket_streambuf]``();
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload1 more...]]``
+
+
+Construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] from the supplied socket.
+
+
+ explicit ``[link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload2 basic_socket_streambuf]``(
+ basic_stream_socket< protocol_type > s);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload2 more...]]``
+
+
+Move-construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] from another.
+
+
+ ``[link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload3 basic_socket_streambuf]``(
+ basic_socket_streambuf && other);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.basic_socket_streambuf.overload3 more...]]``
+
+
+[section:overload1 basic_socket_streambuf::basic_socket_streambuf (1 of 3 overloads)]
+
+
+Construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] without establishing a connection.
+
+
+ basic_socket_streambuf();
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_streambuf::basic_socket_streambuf (2 of 3 overloads)]
+
+
+Construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] from the supplied socket.
+
+
+ basic_socket_streambuf(
+ basic_stream_socket< protocol_type > s);
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_socket_streambuf::basic_socket_streambuf (3 of 3 overloads)]
+
+
+Move-construct a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] from another.
+
+
+ basic_socket_streambuf(
+ basic_socket_streambuf && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:clock_type basic_socket_streambuf::clock_type]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.clock_type..clock_type..basic_socket_streambuf]
+The clock type.
+
+
+ typedef Clock clock_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:close basic_socket_streambuf::close]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.close..close..basic_socket_streambuf]
+Close the connection.
+
+
+ basic_socket_streambuf * close();
+
+
+
+[heading Return Value]
+
+`this` if a connection was successfully established, a null pointer otherwise.
+
+
+
+
+[endsect]
+
+
+[section:connect basic_socket_streambuf::connect]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.connect..connect..basic_socket_streambuf]
+Establish a connection.
+
+
+ basic_socket_streambuf * ``[link asio.reference.basic_socket_streambuf.connect.overload1 connect]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.connect.overload1 more...]]``
+
+ template<
+ typename T1,
+ ... ,
+ typename TN>
+ basic_socket_streambuf * ``[link asio.reference.basic_socket_streambuf.connect.overload2 connect]``(
+ T1 t1,
+ ... ,
+ TN tn);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.connect.overload2 more...]]``
+
+
+[section:overload1 basic_socket_streambuf::connect (1 of 2 overloads)]
+
+
+Establish a connection.
+
+
+ basic_socket_streambuf * connect(
+ const endpoint_type & endpoint);
+
+
+This function establishes a connection to the specified endpoint.
+
+
+[heading Return Value]
+
+`this` if a connection was successfully established, a null pointer otherwise.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_streambuf::connect (2 of 2 overloads)]
+
+
+Establish a connection.
+
+
+ template<
+ typename T1,
+ ... ,
+ typename TN>
+ basic_socket_streambuf * connect(
+ T1 t1,
+ ... ,
+ TN tn);
+
+
+This function automatically establishes a connection based on the supplied resolver query parameters. The arguments are used to construct a resolver query object.
+
+
+[heading Return Value]
+
+`this` if a connection was successfully established, a null pointer otherwise.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:duration basic_socket_streambuf::duration]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.duration..duration..basic_socket_streambuf]
+The duration type.
+
+
+ typedef WaitTraits::duration duration;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:duration_type basic_socket_streambuf::duration_type]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.duration_type..duration_type..basic_socket_streambuf]
+(Deprecated: Use duration.) The duration type.
+
+
+ typedef WaitTraits::duration_type duration_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_socket_streambuf::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.endpoint_type..endpoint_type..basic_socket_streambuf]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error basic_socket_streambuf::error]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.error..error..basic_socket_streambuf]
+Get the last error associated with the stream buffer.
+
+
+ const asio::error_code & error() const;
+
+
+
+[heading Return Value]
+
+An `error_code` corresponding to the last error from the stream buffer.
+
+
+
+
+[endsect]
+
+
+
+[section:expires_after basic_socket_streambuf::expires_after]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.expires_after..expires_after..basic_socket_streambuf]
+Set the stream buffer's expiry time relative to now.
+
+
+ void expires_after(
+ const duration & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:expires_at basic_socket_streambuf::expires_at]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.expires_at..expires_at..basic_socket_streambuf]
+(Deprecated: Use `expiry()`.) Get the stream buffer's expiry time as an absolute time.
+
+
+ time_point ``[link asio.reference.basic_socket_streambuf.expires_at.overload1 expires_at]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.expires_at.overload1 more...]]``
+
+
+Set the stream buffer's expiry time as an absolute time.
+
+
+ void ``[link asio.reference.basic_socket_streambuf.expires_at.overload2 expires_at]``(
+ const time_point & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.expires_at.overload2 more...]]``
+
+
+[section:overload1 basic_socket_streambuf::expires_at (1 of 2 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the stream buffer's expiry time as an absolute time.
+
+
+ time_point expires_at() const;
+
+
+
+[heading Return Value]
+
+An absolute time value representing the stream buffer's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_streambuf::expires_at (2 of 2 overloads)]
+
+
+Set the stream buffer's expiry time as an absolute time.
+
+
+ void expires_at(
+ const time_point & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the stream. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:expires_from_now basic_socket_streambuf::expires_from_now]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.expires_from_now..expires_from_now..basic_socket_streambuf]
+(Deprecated: Use `expiry()`.) Get the stream buffer's expiry time relative to now.
+
+
+ duration ``[link asio.reference.basic_socket_streambuf.expires_from_now.overload1 expires_from_now]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.expires_from_now.overload1 more...]]``
+
+
+(Deprecated: Use `expires_after()`.) Set the stream buffer's expiry time relative to now.
+
+
+ void ``[link asio.reference.basic_socket_streambuf.expires_from_now.overload2 expires_from_now]``(
+ const duration & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_socket_streambuf.expires_from_now.overload2 more...]]``
+
+
+[section:overload1 basic_socket_streambuf::expires_from_now (1 of 2 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the stream buffer's expiry time relative to now.
+
+
+ duration expires_from_now() const;
+
+
+
+[heading Return Value]
+
+A relative time value representing the stream buffer's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_socket_streambuf::expires_from_now (2 of 2 overloads)]
+
+
+(Deprecated: Use `expires_after()`.) Set the stream buffer's expiry time relative to now.
+
+
+ void expires_from_now(
+ const duration & expiry_time);
+
+
+This function sets the expiry time associated with the stream. Stream operations performed after this time (where the operations cannot be completed using the internal buffers) will fail with the error `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:expiry basic_socket_streambuf::expiry]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.expiry..expiry..basic_socket_streambuf]
+Get the stream buffer's expiry time as an absolute time.
+
+
+ time_point expiry() const;
+
+
+
+[heading Return Value]
+
+An absolute time value representing the stream buffer's expiry time.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ basic_socket_streambuf::operator=]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.operator_eq_..operator=..basic_socket_streambuf]
+Move-assign a [link asio.reference.basic_socket_streambuf `basic_socket_streambuf`] from another.
+
+
+ basic_socket_streambuf & operator=(
+ basic_socket_streambuf && other);
+
+
+
+[endsect]
+
+
+
+[section:overflow basic_socket_streambuf::overflow]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.overflow..overflow..basic_socket_streambuf]
+
+ int_type overflow(
+ int_type c);
+
+
+
+[endsect]
+
+
+
+[section:protocol_type basic_socket_streambuf::protocol_type]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.protocol_type..protocol_type..basic_socket_streambuf]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:puberror basic_socket_streambuf::puberror]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.puberror..puberror..basic_socket_streambuf]
+(Deprecated: Use `error()`.) Get the last error associated with the stream buffer.
+
+
+ const asio::error_code & puberror() const;
+
+
+
+[heading Return Value]
+
+An `error_code` corresponding to the last error from the stream buffer.
+
+
+
+
+[endsect]
+
+
+
+[section:setbuf basic_socket_streambuf::setbuf]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.setbuf..setbuf..basic_socket_streambuf]
+
+ std::streambuf * setbuf(
+ char_type * s,
+ std::streamsize n);
+
+
+
+[endsect]
+
+
+
+[section:socket basic_socket_streambuf::socket]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.socket..socket..basic_socket_streambuf]
+Get a reference to the underlying socket.
+
+
+ basic_socket< Protocol > & socket();
+
+
+
+[endsect]
+
+
+
+[section:sync basic_socket_streambuf::sync]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.sync..sync..basic_socket_streambuf]
+
+ int sync();
+
+
+
+[endsect]
+
+
+
+[section:time_point basic_socket_streambuf::time_point]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.time_point..time_point..basic_socket_streambuf]
+The time type.
+
+
+ typedef WaitTraits::time_point time_point;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:time_type basic_socket_streambuf::time_type]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.time_type..time_type..basic_socket_streambuf]
+(Deprecated: Use time\_point.) The time type.
+
+
+ typedef WaitTraits::time_type time_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_socket_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:underflow basic_socket_streambuf::underflow]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf.underflow..underflow..basic_socket_streambuf]
+
+ int_type underflow();
+
+
+
+[endsect]
+
+
+
+[section:_basic_socket_streambuf basic_socket_streambuf::~basic_socket_streambuf]
+
+[indexterm2 asio.indexterm.basic_socket_streambuf._basic_socket_streambuf..~basic_socket_streambuf..basic_socket_streambuf]
+Destructor flushes buffered data.
+
+
+ virtual ~basic_socket_streambuf();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_stream_socket basic_stream_socket]
+
+
+Provides stream-oriented socket functionality.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_stream_socket :
+ public basic_socket< Protocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.basic_stream_socket [*basic_stream_socket]]]
+ [Construct a basic_stream_socket without opening it.
+
+ Construct and open a basic_stream_socket.
+
+ Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_stream_socket on an existing native socket.
+
+ Move-construct a basic_stream_socket from another.
+
+ Move-construct a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_stream_socket from another.
+
+ Move-assign a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.read_some [*read_some]]]
+ [Read some data from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.write_some [*write_some]]]
+ [Write some data to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket._basic_stream_socket [*~basic_stream_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_stream_socket `basic_stream_socket`] class template provides asynchronous and blocking stream-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign basic_stream_socket::assign]
+
+[indexterm2 asio.indexterm.basic_stream_socket.assign..assign..basic_stream_socket]
+Assign an existing native socket to the socket.
+
+
+ void ``[link asio.reference.basic_stream_socket.assign.overload1 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.assign.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.assign.overload2 assign]``(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.assign.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::assign (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::assign (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Assign an existing native socket to the socket.
+
+
+ void assign(
+ const protocol_type & protocol,
+ const native_handle_type & native_socket,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_connect basic_stream_socket::async_connect]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_connect..async_connect..basic_stream_socket]
+Start an asynchronous connect.
+
+
+ template<
+ typename ``[link asio.reference.ConnectHandler ConnectHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_connect(
+ const endpoint_type & peer_endpoint,
+ ConnectHandler && handler);
+
+
+This function is used to asynchronously connect a socket to the specified remote endpoint. The function call always returns immediately.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected. Copies will be made of the endpoint object as required.]]
+
+[[handler][The handler to be called when the connection operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void connect_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Connect succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.async_connect(endpoint, connect_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:async_read_some basic_stream_socket::async_read_some]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_read_some..async_read_some..basic_stream_socket]
+Start an asynchronous read.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data from the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The read operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_read_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[section:async_receive basic_stream_socket::async_receive]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_receive..async_receive..basic_stream_socket]
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_stream_socket.async_receive.overload1 async_receive]``(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.async_receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_stream_socket.async_receive.overload2 async_receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.async_receive.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::async_receive (1 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is received before the asynchronous operation completes.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::async_receive (2 of 2 overloads)]
+
+
+Start an asynchronous receive.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously receive data from the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes received.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is received before the asynchronous operation completes.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_receive(asio::buffer(data, size), 0, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:async_send basic_stream_socket::async_send]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_send..async_send..basic_stream_socket]
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_stream_socket.async_send.overload1 async_send]``(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.async_send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.basic_stream_socket.async_send.overload2 async_send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.async_send.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::async_send (1 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send data on the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_send(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::async_send (2 of 2 overloads)]
+
+
+Start an asynchronous send.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously send data on the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes sent.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_send(asio::buffer(data, size), 0, handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait basic_stream_socket::async_wait]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_wait..async_wait..basic_stream_socket]
+Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some basic_stream_socket::async_write_some]
+
+[indexterm2 asio.indexterm.basic_stream_socket.async_write_some..async_write_some..basic_stream_socket]
+Start an asynchronous write.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write data to the stream socket. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the socket. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The write operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.async_write_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[section:at_mark basic_stream_socket::at_mark]
+
+[indexterm2 asio.indexterm.basic_stream_socket.at_mark..at_mark..basic_stream_socket]
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool ``[link asio.reference.basic_stream_socket.at_mark.overload1 at_mark]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.at_mark.overload1 more...]]``
+
+ bool ``[link asio.reference.basic_stream_socket.at_mark.overload2 at_mark]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.at_mark.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::at_mark (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark() const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::at_mark (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine whether the socket is at the out-of-band data mark.
+
+
+ bool at_mark(
+ asio::error_code & ec) const;
+
+
+This function is used to check whether the socket input is currently positioned at the out-of-band data mark.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A bool indicating whether the socket is at the out-of-band data mark.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:available basic_stream_socket::available]
+
+[indexterm2 asio.indexterm.basic_stream_socket.available..available..basic_stream_socket]
+Determine the number of bytes available for reading.
+
+
+ std::size_t ``[link asio.reference.basic_stream_socket.available.overload1 available]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.available.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.basic_stream_socket.available.overload2 available]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.available.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::available (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available() const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::available (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Determine the number of bytes available for reading.
+
+
+ std::size_t available(
+ asio::error_code & ec) const;
+
+
+This function is used to determine the number of bytes that may be read without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes that may be read without blocking, or 0 if an error occurs.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_stream_socket basic_stream_socket::basic_stream_socket]
+
+[indexterm2 asio.indexterm.basic_stream_socket.basic_stream_socket..basic_stream_socket..basic_stream_socket]
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] without opening it.
+
+
+ explicit ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload1 basic_stream_socket]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.basic_stream_socket `basic_stream_socket`].
+
+
+ ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload2 basic_stream_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload2 more...]]``
+
+
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`], opening it and binding it to the given local endpoint.
+
+
+ ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload3 basic_stream_socket]``(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload3 more...]]``
+
+
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] on an existing native socket.
+
+
+ ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload4 basic_stream_socket]``(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] from another.
+
+
+ ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload5 basic_stream_socket]``(
+ basic_stream_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload5 more...]]``
+
+
+Move-construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ ``[link asio.reference.basic_stream_socket.basic_stream_socket.overload6 basic_stream_socket]``(
+ basic_stream_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.basic_stream_socket.overload6 more...]]``
+
+
+[section:overload1 basic_stream_socket::basic_stream_socket (1 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] without opening it.
+
+
+ basic_stream_socket(
+ asio::io_context & io_context);
+
+
+This constructor creates a stream socket without opening it. The socket needs to be opened and then connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream socket will use to dispatch handlers for any asynchronous operations performed on the socket. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::basic_stream_socket (2 of 6 overloads)]
+
+
+Construct and open a [link asio.reference.basic_stream_socket `basic_stream_socket`].
+
+
+ basic_stream_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol);
+
+
+This constructor creates and opens a stream socket. The socket needs to be connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_stream_socket::basic_stream_socket (3 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`], opening it and binding it to the given local endpoint.
+
+
+ basic_stream_socket(
+ asio::io_context & io_context,
+ const endpoint_type & endpoint);
+
+
+This constructor creates a stream socket and automatically opens it bound to the specified endpoint on the local machine. The protocol used is the protocol associated with the given endpoint.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[endpoint][An endpoint on the local machine to which the stream socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_stream_socket::basic_stream_socket (4 of 6 overloads)]
+
+
+Construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] on an existing native socket.
+
+
+ basic_stream_socket(
+ asio::io_context & io_context,
+ const protocol_type & protocol,
+ const native_handle_type & native_socket);
+
+
+This constructor creates a stream socket object to hold an existing native socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream socket will use to dispatch handlers for any asynchronous operations performed on the socket.]]
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+[[native_socket][The new underlying socket implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 basic_stream_socket::basic_stream_socket (5 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] from another.
+
+
+ basic_stream_socket(
+ basic_stream_socket && other);
+
+
+This constructor moves a stream socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_stream_socket `basic_stream_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_stream_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 basic_stream_socket::basic_stream_socket (6 of 6 overloads)]
+
+
+Move-construct a [link asio.reference.basic_stream_socket `basic_stream_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ basic_stream_socket(
+ basic_stream_socket< Protocol1 > && other,
+ typename enable_if< is_convertible< Protocol1, Protocol >::value >::type * = 0);
+
+
+This constructor moves a stream socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_stream_socket `basic_stream_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_stream_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:bind basic_stream_socket::bind]
+
+[indexterm2 asio.indexterm.basic_stream_socket.bind..bind..basic_stream_socket]
+Bind the socket to the given local endpoint.
+
+
+ void ``[link asio.reference.basic_stream_socket.bind.overload1 bind]``(
+ const endpoint_type & endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.bind.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.bind.overload2 bind]``(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.bind.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::bind (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::bind (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Bind the socket to the given local endpoint.
+
+
+ void bind(
+ const endpoint_type & endpoint,
+ asio::error_code & ec);
+
+
+This function binds the socket to the specified endpoint on the local machine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[endpoint][An endpoint on the local machine to which the socket will be bound.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+ asio::error_code ec;
+ socket.bind(asio::ip::tcp::endpoint(
+ asio::ip::tcp::v4(), 12345), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:broadcast basic_stream_socket::broadcast]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.broadcast..broadcast..basic_stream_socket]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable basic_stream_socket::bytes_readable]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.bytes_readable..bytes_readable..basic_stream_socket]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel basic_stream_socket::cancel]
+
+[indexterm2 asio.indexterm.basic_stream_socket.cancel..cancel..basic_stream_socket]
+Cancel all asynchronous operations associated with the socket.
+
+
+ void ``[link asio.reference.basic_stream_socket.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::cancel (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::cancel (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Cancel all asynchronous operations associated with the socket.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls to `cancel()` will always fail with `asio::error::operation_not_supported` when run on Windows XP, Windows Server 2003, and earlier versions of Windows, unless ASIO\_ENABLE\_CANCELIO is defined. However, the CancelIo function has two issues that should be considered before enabling its use:
+
+
+* It will only cancel asynchronous operations that were initiated in the current thread.
+
+
+* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.
+
+For portable cancellation, consider using one of the following alternatives:
+
+
+* Disable asio's I/O completion port backend by defining ASIO\_DISABLE\_IOCP.
+
+
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
+
+When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close basic_stream_socket::close]
+
+[indexterm2 asio.indexterm.basic_stream_socket.close..close..basic_stream_socket]
+Close the socket.
+
+
+ void ``[link asio.reference.basic_stream_socket.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.close.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.close.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::close (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close();
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::close (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Close the socket.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the socket. Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.close(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+[heading Remarks]
+
+For portable behaviour with respect to graceful closure of a connected socket, call `shutdown()` before closing the socket.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:connect basic_stream_socket::connect]
+
+[indexterm2 asio.indexterm.basic_stream_socket.connect..connect..basic_stream_socket]
+Connect the socket to the specified endpoint.
+
+
+ void ``[link asio.reference.basic_stream_socket.connect.overload1 connect]``(
+ const endpoint_type & peer_endpoint);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.connect.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.connect.overload2 connect]``(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.connect.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::connect (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ socket.connect(endpoint);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::connect (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Connect the socket to the specified endpoint.
+
+
+ void connect(
+ const endpoint_type & peer_endpoint,
+ asio::error_code & ec);
+
+
+This function is used to connect a socket to the specified remote endpoint. The function call will block until the connection is successfully made or an error occurs.
+
+The socket is automatically opened if it is not already open. If the connect fails, and the socket was automatically opened, the socket is not returned to the closed state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[peer_endpoint][The remote endpoint to which the socket will be connected.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::ip::tcp::endpoint endpoint(
+ asio::ip::address::from_string("1.2.3.4"), 12345);
+ asio::error_code ec;
+ socket.connect(endpoint, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:debug basic_stream_socket::debug]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.debug..debug..basic_stream_socket]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route basic_stream_socket::do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.do_not_route..do_not_route..basic_stream_socket]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted basic_stream_socket::enable_connection_aborted]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.enable_connection_aborted..enable_connection_aborted..basic_stream_socket]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint_type basic_stream_socket::endpoint_type]
+
+[indexterm2 asio.indexterm.basic_stream_socket.endpoint_type..endpoint_type..basic_stream_socket]
+The endpoint type.
+
+
+ typedef Protocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_stream_socket::executor_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.executor_type..executor_type..basic_stream_socket]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor basic_stream_socket::get_executor]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.get_executor..get_executor..basic_stream_socket]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_stream_socket::get_io_context]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.get_io_context..get_io_context..basic_stream_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_stream_socket::get_io_service]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.get_io_service..get_io_service..basic_stream_socket]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option basic_stream_socket::get_option]
+
+[indexterm2 asio.indexterm.basic_stream_socket.get_option..get_option..basic_stream_socket]
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_stream_socket.get_option.overload1 get_option]``(
+ GettableSocketOption & option) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void ``[link asio.reference.basic_stream_socket.get_option.overload2 get_option]``(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.get_option.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::get_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::get_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get an option from the socket.
+
+
+ template<
+ typename ``[link asio.reference.GettableSocketOption GettableSocketOption]``>
+ void get_option(
+ GettableSocketOption & option,
+ asio::error_code & ec) const;
+
+
+This function is used to get the current value of an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the value of the SOL\_SOCKET/SO\_KEEPALIVE option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::keep_alive option;
+ asio::error_code ec;
+ socket.get_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:io_control basic_stream_socket::io_control]
+
+[indexterm2 asio.indexterm.basic_stream_socket.io_control..io_control..basic_stream_socket]
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_stream_socket.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.basic_stream_socket.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.io_control.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::io_control (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::io_control (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Perform an IO control command on the socket.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::socket::bytes_readable command;
+ asio::error_code ec;
+ socket.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open basic_stream_socket::is_open]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.is_open..is_open..basic_stream_socket]
+Determine whether the socket is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+
+[section:keep_alive basic_stream_socket::keep_alive]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.keep_alive..keep_alive..basic_stream_socket]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger basic_stream_socket::linger]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.linger..linger..basic_stream_socket]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:local_endpoint basic_stream_socket::local_endpoint]
+
+[indexterm2 asio.indexterm.basic_stream_socket.local_endpoint..local_endpoint..basic_stream_socket]
+Get the local endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_stream_socket.local_endpoint.overload1 local_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.local_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_stream_socket.local_endpoint.overload2 local_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.local_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::local_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint() const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::local_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the local endpoint of the socket.
+
+
+ endpoint_type local_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the locally bound endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the local endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer basic_stream_socket::lowest_layer]
+
+[indexterm2 asio.indexterm.basic_stream_socket.lowest_layer..lowest_layer..basic_stream_socket]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.basic_stream_socket.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.basic_stream_socket.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.basic_socket `basic_socket`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type basic_stream_socket::lowest_layer_type]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.lowest_layer_type..lowest_layer_type..basic_stream_socket]
+A [link asio.reference.basic_socket `basic_socket`] is always the lowest layer.
+
+
+ typedef basic_socket< Protocol > lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.basic_socket [*basic_socket]]]
+ [Construct a basic_socket without opening it.
+
+ Construct and open a basic_socket.
+
+ Construct a basic_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_socket on an existing native socket.
+
+ Move-construct a basic_socket from another.
+
+ Move-construct a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket from another.
+
+ Move-assign a basic_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket._basic_socket [*~basic_socket]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket `basic_socket`] class template provides functionality that is common to both stream-oriented and datagram-oriented sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections basic_stream_socket::max_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.max_connections..max_connections..basic_stream_socket]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections basic_stream_socket::max_listen_connections]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.max_listen_connections..max_listen_connections..basic_stream_socket]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route basic_stream_socket::message_do_not_route]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.message_do_not_route..message_do_not_route..basic_stream_socket]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record basic_stream_socket::message_end_of_record]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.message_end_of_record..message_end_of_record..basic_stream_socket]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags basic_stream_socket::message_flags]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.message_flags..message_flags..basic_stream_socket]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band basic_stream_socket::message_out_of_band]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.message_out_of_band..message_out_of_band..basic_stream_socket]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek basic_stream_socket::message_peek]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.message_peek..message_peek..basic_stream_socket]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:native_handle basic_stream_socket::native_handle]
+
+
+['Inherited from basic_socket.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.native_handle..native_handle..basic_stream_socket]
+Get the native socket representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the socket. This is intended to allow access to native socket functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type basic_stream_socket::native_handle_type]
+
+[indexterm2 asio.indexterm.basic_stream_socket.native_handle_type..native_handle_type..basic_stream_socket]
+The native representation of a socket.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking basic_stream_socket::native_non_blocking]
+
+[indexterm2 asio.indexterm.basic_stream_socket.native_non_blocking..native_non_blocking..basic_stream_socket]
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool ``[link asio.reference.basic_stream_socket.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void ``[link asio.reference.basic_stream_socket.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_stream_socket::native_non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the native socket implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native socket. This mode has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying socket is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the socket object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native socket.
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::native_non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_stream_socket::native_non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the native socket implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native socket. It has no effect on the behaviour of the socket object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying socket is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense.]]
+
+]
+
+
+[heading Example]
+
+This function is intended to allow the encapsulation of arbitrary non-blocking system calls as asynchronous operations, in a way that is transparent to the user of the socket object. The following example illustrates how Linux's `sendfile` system call might be encapsulated:
+
+ template <typename Handler>
+ struct sendfile_op
+ {
+ tcp::socket& sock_;
+ int fd_;
+ Handler handler_;
+ off_t offset_;
+ std::size_t total_bytes_transferred_;
+
+ // Function call operator meeting WriteHandler requirements.
+ // Used as the handler for the async_write_some operation.
+ void operator()(asio::error_code ec, std::size_t)
+ {
+ // Put the underlying socket into non-blocking mode.
+ if (!ec)
+ if (!sock_.native_non_blocking())
+ sock_.native_non_blocking(true, ec);
+
+ if (!ec)
+ {
+ for (;;)
+ {
+ // Try the system call.
+ errno = 0;
+ int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ ec = asio::error_code(n < 0 ? errno : 0,
+ asio::error::get_system_category());
+ total_bytes_transferred_ += ec ? 0 : n;
+
+ // Retry operation immediately if interrupted by signal.
+ if (ec == asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == asio::error::would_block
+ || ec == asio::error::try_again)
+ {
+ // We have to wait for the socket to become ready again.
+ sock_.async_wait(tcp::socket::wait_write, *this);
+ return;
+ }
+
+ if (ec || n == 0)
+ {
+ // An error occurred, or we have reached the end of the file.
+ // Either way we must exit the loop so we can call the handler.
+ break;
+ }
+
+ // Loop around to try calling sendfile again.
+ }
+ }
+
+ // Pass result back to user's handler.
+ handler_(ec, total_bytes_transferred_);
+ }
+ };
+
+ template <typename Handler>
+ void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ {
+ sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ sock.async_wait(tcp::socket::wait_write, op);
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking basic_stream_socket::non_blocking]
+
+[indexterm2 asio.indexterm.basic_stream_socket.non_blocking..non_blocking..basic_stream_socket]
+Gets the non-blocking mode of the socket.
+
+
+ bool ``[link asio.reference.basic_stream_socket.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void ``[link asio.reference.basic_stream_socket.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.non_blocking.overload3 more...]]``
+
+
+[section:overload1 basic_stream_socket::non_blocking (1 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Gets the non-blocking mode of the socket.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::non_blocking (2 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_stream_socket::non_blocking (3 of 3 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Sets the non-blocking mode of the socket.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the socket's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:open basic_stream_socket::open]
+
+[indexterm2 asio.indexterm.basic_stream_socket.open..open..basic_stream_socket]
+Open the socket using the specified protocol.
+
+
+ void ``[link asio.reference.basic_stream_socket.open.overload1 open]``(
+ const protocol_type & protocol = protocol_type());
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.open.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.open.overload2 open]``(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.open.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::open (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol = protocol_type());
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying protocol parameters to be used.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ socket.open(asio::ip::tcp::v4());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::open (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Open the socket using the specified protocol.
+
+
+ void open(
+ const protocol_type & protocol,
+ asio::error_code & ec);
+
+
+This function opens the socket so that it will use the specified protocol.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][An object specifying which protocol is to be used.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ asio::error_code ec;
+ socket.open(asio::ip::tcp::v4(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq_ basic_stream_socket::operator=]
+
+[indexterm2 asio.indexterm.basic_stream_socket.operator_eq_..operator=..basic_stream_socket]
+Move-assign a [link asio.reference.basic_stream_socket `basic_stream_socket`] from another.
+
+
+ basic_stream_socket & ``[link asio.reference.basic_stream_socket.operator_eq_.overload1 operator=]``(
+ basic_stream_socket && other);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.operator_eq_.overload1 more...]]``
+
+
+Move-assign a [link asio.reference.basic_stream_socket `basic_stream_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_stream_socket >::type & ``[link asio.reference.basic_stream_socket.operator_eq_.overload2 operator=]``(
+ basic_stream_socket< Protocol1 > && other);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::operator= (1 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_stream_socket `basic_stream_socket`] from another.
+
+
+ basic_stream_socket & operator=(
+ basic_stream_socket && other);
+
+
+This assignment operator moves a stream socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_stream_socket `basic_stream_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_stream_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::operator= (2 of 2 overloads)]
+
+
+Move-assign a [link asio.reference.basic_stream_socket `basic_stream_socket`] from a socket of another protocol type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol1]``>
+ enable_if< is_convertible< Protocol1, Protocol >::value, basic_stream_socket >::type & operator=(
+ basic_stream_socket< Protocol1 > && other);
+
+
+This assignment operator moves a stream socket from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_stream_socket `basic_stream_socket`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_stream_socket(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol_type basic_stream_socket::protocol_type]
+
+[indexterm2 asio.indexterm.basic_stream_socket.protocol_type..protocol_type..basic_stream_socket]
+The protocol type.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:read_some basic_stream_socket::read_some]
+
+[indexterm2 asio.indexterm.basic_stream_socket.read_some..read_some..basic_stream_socket]
+Read some data from the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.read_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.read_some.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::read_some (1 of 2 overloads)]
+
+
+Read some data from the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the stream socket. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.read_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::read_some (2 of 2 overloads)]
+
+
+Read some data from the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the stream socket. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:receive basic_stream_socket::receive]
+
+[indexterm2 asio.indexterm.basic_stream_socket.receive..receive..basic_stream_socket]
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.receive.overload1 receive]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.receive.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.receive.overload2 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.receive.overload2 more...]]``
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.receive.overload3 receive]``(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.receive.overload3 more...]]``
+
+
+[section:overload1 basic_stream_socket::receive (1 of 3 overloads)]
+
+
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to receive data on the stream socket. The function call will block until one or more bytes of data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::receive (2 of 3 overloads)]
+
+
+Receive some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+This function is used to receive data on the stream socket. The function call will block until one or more bytes of data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To receive into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.receive(asio::buffer(data, size), 0);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on receiving into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_stream_socket::receive (3 of 3 overloads)]
+
+
+Receive some data on a connected socket.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t receive(
+ const MutableBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+This function is used to receive data on the stream socket. The function call will block until one or more bytes of data has been received successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be received.]]
+
+[[flags][Flags specifying how the receive call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes received. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The receive operation may not receive all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:receive_buffer_size basic_stream_socket::receive_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.receive_buffer_size..receive_buffer_size..basic_stream_socket]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_low_watermark basic_stream_socket::receive_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.receive_low_watermark..receive_low_watermark..basic_stream_socket]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:remote_endpoint basic_stream_socket::remote_endpoint]
+
+[indexterm2 asio.indexterm.basic_stream_socket.remote_endpoint..remote_endpoint..basic_stream_socket]
+Get the remote endpoint of the socket.
+
+
+ endpoint_type ``[link asio.reference.basic_stream_socket.remote_endpoint.overload1 remote_endpoint]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.remote_endpoint.overload1 more...]]``
+
+ endpoint_type ``[link asio.reference.basic_stream_socket.remote_endpoint.overload2 remote_endpoint]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.remote_endpoint.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::remote_endpoint (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint() const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::remote_endpoint (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Get the remote endpoint of the socket.
+
+
+ endpoint_type remote_endpoint(
+ asio::error_code & ec) const;
+
+
+This function is used to obtain the remote endpoint of the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+An object that represents the remote endpoint of the socket. Returns a default-constructed endpoint object if an error occurred.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:reuse_address basic_stream_socket::reuse_address]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.reuse_address..reuse_address..basic_stream_socket]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:send basic_stream_socket::send]
+
+[indexterm2 asio.indexterm.basic_stream_socket.send..send..basic_stream_socket]
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.send.overload1 send]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.send.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.send.overload2 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.send.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.send.overload3 send]``(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.send.overload3 more...]]``
+
+
+[section:overload1 basic_stream_socket::send (1 of 3 overloads)]
+
+
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to send data on the stream socket. The function call will block until one or more bytes of the data has been sent successfully, or an until error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.send(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::send (2 of 3 overloads)]
+
+
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags);
+
+
+This function is used to send data on the stream socket. The function call will block until one or more bytes of the data has been sent successfully, or an until error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To send a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.send(asio::buffer(data, size), 0);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on sending multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_stream_socket::send (3 of 3 overloads)]
+
+
+Send some data on the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t send(
+ const ConstBufferSequence & buffers,
+ socket_base::message_flags flags,
+ asio::error_code & ec);
+
+
+This function is used to send data on the stream socket. The function call will block until one or more bytes of the data has been sent successfully, or an until error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be sent on the socket.]]
+
+[[flags][Flags specifying how the send call is to be made.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes sent. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The send operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:send_buffer_size basic_stream_socket::send_buffer_size]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.send_buffer_size..send_buffer_size..basic_stream_socket]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark basic_stream_socket::send_low_watermark]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.send_low_watermark..send_low_watermark..basic_stream_socket]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_stream_socket.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:set_option basic_stream_socket::set_option]
+
+[indexterm2 asio.indexterm.basic_stream_socket.set_option..set_option..basic_stream_socket]
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_stream_socket.set_option.overload1 set_option]``(
+ const SettableSocketOption & option);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void ``[link asio.reference.basic_stream_socket.set_option.overload2 set_option]``(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.set_option.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::set_option (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::set_option (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Set an option on the socket.
+
+
+ template<
+ typename ``[link asio.reference.SettableSocketOption SettableSocketOption]``>
+ void set_option(
+ const SettableSocketOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the socket.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The new option value to be set on the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Setting the IPPROTO\_TCP/TCP\_NODELAY option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ asio::error_code ec;
+ socket.set_option(option, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown basic_stream_socket::shutdown]
+
+[indexterm2 asio.indexterm.basic_stream_socket.shutdown..shutdown..basic_stream_socket]
+Disable sends or receives on the socket.
+
+
+ void ``[link asio.reference.basic_stream_socket.shutdown.overload1 shutdown]``(
+ shutdown_type what);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.shutdown.overload2 shutdown]``(
+ shutdown_type what,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.shutdown.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::shutdown (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::shutdown (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Disable sends or receives on the socket.
+
+
+ void shutdown(
+ shutdown_type what,
+ asio::error_code & ec);
+
+
+This function is used to disable send operations, receive operations, or both.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[what][Determines what types of operation will no longer be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Shutting down the send side of the socket:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:shutdown_type basic_stream_socket::shutdown_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.shutdown_type..shutdown_type..basic_stream_socket]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.basic_stream_socket.shutdown_type.shutdown_receive..shutdown_receive..basic_stream_socket]
+[indexterm2 asio.indexterm.basic_stream_socket.shutdown_type.shutdown_send..shutdown_send..basic_stream_socket]
+[indexterm2 asio.indexterm.basic_stream_socket.shutdown_type.shutdown_both..shutdown_both..basic_stream_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:wait basic_stream_socket::wait]
+
+[indexterm2 asio.indexterm.basic_stream_socket.wait..wait..basic_stream_socket]
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.basic_stream_socket.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_stream_socket.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.wait.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::wait (1 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ socket.wait(asio::ip::tcp::socket::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::wait (2 of 2 overloads)]
+
+
+['Inherited from basic_socket.]
+
+
+Wait for the socket to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a socket to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired socket state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a socket to become readable.
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::error_code ec;
+ socket.wait(asio::ip::tcp::socket::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type basic_stream_socket::wait_type]
+
+
+['Inherited from socket_base.]
+
+[indexterm2 asio.indexterm.basic_stream_socket.wait_type..wait_type..basic_stream_socket]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.basic_stream_socket.wait_type.wait_read..wait_read..basic_stream_socket]
+[indexterm2 asio.indexterm.basic_stream_socket.wait_type.wait_write..wait_write..basic_stream_socket]
+[indexterm2 asio.indexterm.basic_stream_socket.wait_type.wait_error..wait_error..basic_stream_socket]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+[section:write_some basic_stream_socket::write_some]
+
+[indexterm2 asio.indexterm.basic_stream_socket.write_some..write_some..basic_stream_socket]
+Write some data to the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.write_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.basic_stream_socket.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_stream_socket.write_some.overload2 more...]]``
+
+
+[section:overload1 basic_stream_socket::write_some (1 of 2 overloads)]
+
+
+Write some data to the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data to the stream socket. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the socket.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ socket.write_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_stream_socket::write_some (2 of 2 overloads)]
+
+
+Write some data to the socket.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data to the stream socket. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the socket.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_basic_stream_socket basic_stream_socket::~basic_stream_socket]
+
+[indexterm2 asio.indexterm.basic_stream_socket._basic_stream_socket..~basic_stream_socket..basic_stream_socket]
+Destroys the socket.
+
+
+ ~basic_stream_socket();
+
+
+This function destroys the socket, cancelling any outstanding asynchronous operations associated with the socket as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_streambuf basic_streambuf]
+
+
+Automatically resizable buffer class based on std::streambuf.
+
+
+ template<
+ typename Allocator = std::allocator<char>>
+ class basic_streambuf :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_streambuf.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_streambuf.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.basic_streambuf [*basic_streambuf]]]
+ [Construct a basic_streambuf object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.capacity [*capacity]]]
+ [Get the current capacity of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.commit [*commit]]]
+ [Move characters from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.max_size [*max_size]]]
+ [Get the maximum size of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.overflow [*overflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.reserve [*reserve]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.underflow [*underflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+]
+
+The `basic_streambuf` class is derived from `std::streambuf` to associate the streambuf's input and output sequences with one or more character arrays. These character arrays are internal to the `basic_streambuf` object, but direct access to the array elements is provided to permit them to be used efficiently with I/O operations. Characters written to the output sequence of a `basic_streambuf` object are appended to the input sequence of the same object.
+
+The `basic_streambuf` class's public interface is intended to permit the following implementation strategies:
+
+
+* A single contiguous character array, which is reallocated as necessary to accommodate changes in the size of the character sequence. This is the implementation approach currently used in Asio.
+
+
+* A sequence of one or more character arrays, where each array is of the same size. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+
+* A sequence of one or more character arrays of varying sizes. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+The constructor for [link asio.reference.basic_streambuf `basic_streambuf`] accepts a `size_t` argument specifying the maximum of the sum of the sizes of the input sequence and output sequence. During the lifetime of the `basic_streambuf` object, the following invariant holds:
+
+ size() <= max_size()
+
+
+Any member function that would, if successful, cause the invariant to be violated shall throw an exception of class `std::length_error`.
+
+The constructor for `basic_streambuf` takes an Allocator argument. A copy of this argument is used for any memory allocation performed, by the constructor and by all member functions, during the lifetime of each `basic_streambuf` object.
+
+
+[heading Examples]
+
+Writing directly from an streambuf to a socket:
+
+ asio::streambuf b;
+ std::ostream os(&b);
+ os << "Hello, World!\n";
+
+ // try sending some data in input sequence
+ size_t n = sock.send(b.data());
+
+ b.consume(n); // sent data is removed from input sequence
+
+
+
+
+Reading from a socket directly into a streambuf:
+
+ asio::streambuf b;
+
+ // reserve 512 bytes in output sequence
+ asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
+
+ size_t n = sock.receive(bufs);
+
+ // received data is "committed" from output sequence to input sequence
+ b.commit(n);
+
+ std::istream is(&b);
+ std::string s;
+ is >> s;
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:basic_streambuf basic_streambuf::basic_streambuf]
+
+[indexterm2 asio.indexterm.basic_streambuf.basic_streambuf..basic_streambuf..basic_streambuf]
+Construct a [link asio.reference.basic_streambuf `basic_streambuf`] object.
+
+
+ basic_streambuf(
+ std::size_t maximum_size = (std::numeric_limits< std::size_t >::max)(),
+ const Allocator & allocator = Allocator());
+
+
+Constructs a streambuf with the specified maximum size. The initial size of the streambuf's input sequence is 0.
+
+
+[endsect]
+
+
+
+[section:capacity basic_streambuf::capacity]
+
+[indexterm2 asio.indexterm.basic_streambuf.capacity..capacity..basic_streambuf]
+Get the current capacity of the [link asio.reference.basic_streambuf `basic_streambuf`].
+
+
+ std::size_t capacity() const;
+
+
+
+[heading Return Value]
+
+The current total capacity of the streambuf, i.e. for both the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:commit basic_streambuf::commit]
+
+[indexterm2 asio.indexterm.basic_streambuf.commit..commit..basic_streambuf]
+Move characters from the output sequence to the input sequence.
+
+
+ void commit(
+ std::size_t n);
+
+
+Appends `n` characters from the start of the output sequence to the input sequence. The beginning of the output sequence is advanced by `n` characters.
+
+Requires a preceding call `prepare(x)` where `x >= n`, and no intervening operations that modify the input or output sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the output sequence, the entire output sequence is moved to the input sequence and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:const_buffers_type basic_streambuf::const_buffers_type]
+
+[indexterm2 asio.indexterm.basic_streambuf.const_buffers_type..const_buffers_type..basic_streambuf]
+The type used to represent the input sequence as a list of buffers.
+
+
+ typedef implementation_defined const_buffers_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:consume basic_streambuf::consume]
+
+[indexterm2 asio.indexterm.basic_streambuf.consume..consume..basic_streambuf]
+Remove characters from the input sequence.
+
+
+ void consume(
+ std::size_t n);
+
+
+Removes `n` characters from the beginning of the input sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the input sequence, the entire input sequence is consumed and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:data basic_streambuf::data]
+
+[indexterm2 asio.indexterm.basic_streambuf.data..data..basic_streambuf]
+Get a list of buffers that represents the input sequence.
+
+
+ const_buffers_type data() const;
+
+
+
+[heading Return Value]
+
+An object of type `const_buffers_type` that satisfies ConstBufferSequence requirements, representing all character arrays in the input sequence.
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `basic_streambuf` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:max_size basic_streambuf::max_size]
+
+[indexterm2 asio.indexterm.basic_streambuf.max_size..max_size..basic_streambuf]
+Get the maximum size of the [link asio.reference.basic_streambuf `basic_streambuf`].
+
+
+ std::size_t max_size() const;
+
+
+
+[heading Return Value]
+
+The allowed maximum of the sum of the sizes of the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:mutable_buffers_type basic_streambuf::mutable_buffers_type]
+
+[indexterm2 asio.indexterm.basic_streambuf.mutable_buffers_type..mutable_buffers_type..basic_streambuf]
+The type used to represent the output sequence as a list of buffers.
+
+
+ typedef implementation_defined mutable_buffers_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overflow basic_streambuf::overflow]
+
+[indexterm2 asio.indexterm.basic_streambuf.overflow..overflow..basic_streambuf]
+Override std::streambuf behaviour.
+
+
+ int_type overflow(
+ int_type c);
+
+
+Behaves according to the specification of `std::streambuf::overflow()`, with the specialisation that `std::length_error` is thrown if appending the character to the input sequence would require the condition `size() > max_size()` to be true.
+
+
+[endsect]
+
+
+
+[section:prepare basic_streambuf::prepare]
+
+[indexterm2 asio.indexterm.basic_streambuf.prepare..prepare..basic_streambuf]
+Get a list of buffers that represents the output sequence, with the given size.
+
+
+ mutable_buffers_type prepare(
+ std::size_t n);
+
+
+Ensures that the output sequence can accommodate `n` characters, reallocating character array objects as necessary.
+
+
+[heading Return Value]
+
+An object of type `mutable_buffers_type` that satisfies MutableBufferSequence requirements, representing character array objects at the start of the output sequence such that the sum of the buffer sizes is `n`.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[std::length_error][If `size() + n > max_size()`.]]
+
+]
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `basic_streambuf` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:reserve basic_streambuf::reserve]
+
+[indexterm2 asio.indexterm.basic_streambuf.reserve..reserve..basic_streambuf]
+
+ void reserve(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size basic_streambuf::size]
+
+[indexterm2 asio.indexterm.basic_streambuf.size..size..basic_streambuf]
+Get the size of the input sequence.
+
+
+ std::size_t size() const;
+
+
+
+[heading Return Value]
+
+The size of the input sequence. The value is equal to that calculated for `s` in the following code:
+
+ size_t s = 0;
+ const_buffers_type bufs = data();
+ const_buffers_type::const_iterator i = bufs.begin();
+ while (i != bufs.end())
+ {
+ const_buffer buf(*i++);
+ s += buf.size();
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:underflow basic_streambuf::underflow]
+
+[indexterm2 asio.indexterm.basic_streambuf.underflow..underflow..basic_streambuf]
+Override std::streambuf behaviour.
+
+
+ int_type underflow();
+
+
+Behaves according to the specification of `std::streambuf::underflow()`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_streambuf_ref basic_streambuf_ref]
+
+
+Adapts [link asio.reference.basic_streambuf `basic_streambuf`] to the dynamic buffer sequence type requirements.
+
+
+ template<
+ typename Allocator = std::allocator<char>>
+ class basic_streambuf_ref
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_streambuf_ref.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_streambuf_ref.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.basic_streambuf_ref [*basic_streambuf_ref]]]
+ [Construct a basic_streambuf_ref for the given basic_streambuf object.
+
+ Copy construct a basic_streambuf_ref.
+
+ Move construct a basic_streambuf_ref. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.capacity [*capacity]]]
+ [Get the current capacity of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.commit [*commit]]]
+ [Move bytes from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.max_size [*max_size]]]
+ [Get the maximum size of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf_ref.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_streambuf_ref basic_streambuf_ref::basic_streambuf_ref]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.basic_streambuf_ref..basic_streambuf_ref..basic_streambuf_ref]
+Construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`] for the given [link asio.reference.basic_streambuf `basic_streambuf`] object.
+
+
+ explicit ``[link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload1 basic_streambuf_ref]``(
+ basic_streambuf< Allocator > & sb);
+ `` [''''&raquo;''' [link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload1 more...]]``
+
+
+Copy construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`].
+
+
+ ``[link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload2 basic_streambuf_ref]``(
+ const basic_streambuf_ref & other);
+ `` [''''&raquo;''' [link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload2 more...]]``
+
+
+Move construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`].
+
+
+ ``[link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload3 basic_streambuf_ref]``(
+ basic_streambuf_ref && other);
+ `` [''''&raquo;''' [link asio.reference.basic_streambuf_ref.basic_streambuf_ref.overload3 more...]]``
+
+
+[section:overload1 basic_streambuf_ref::basic_streambuf_ref (1 of 3 overloads)]
+
+
+Construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`] for the given [link asio.reference.basic_streambuf `basic_streambuf`] object.
+
+
+ basic_streambuf_ref(
+ basic_streambuf< Allocator > & sb);
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_streambuf_ref::basic_streambuf_ref (2 of 3 overloads)]
+
+
+Copy construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`].
+
+
+ basic_streambuf_ref(
+ const basic_streambuf_ref & other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_streambuf_ref::basic_streambuf_ref (3 of 3 overloads)]
+
+
+Move construct a [link asio.reference.basic_streambuf_ref `basic_streambuf_ref`].
+
+
+ basic_streambuf_ref(
+ basic_streambuf_ref && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:capacity basic_streambuf_ref::capacity]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.capacity..capacity..basic_streambuf_ref]
+Get the current capacity of the dynamic buffer.
+
+
+ std::size_t capacity() const;
+
+
+
+[endsect]
+
+
+
+[section:commit basic_streambuf_ref::commit]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.commit..commit..basic_streambuf_ref]
+Move bytes from the output sequence to the input sequence.
+
+
+ void commit(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:const_buffers_type basic_streambuf_ref::const_buffers_type]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.const_buffers_type..const_buffers_type..basic_streambuf_ref]
+The type used to represent the input sequence as a list of buffers.
+
+
+ typedef basic_streambuf< Allocator >::const_buffers_type const_buffers_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_streambuf.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_streambuf.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.basic_streambuf [*basic_streambuf]]]
+ [Construct a basic_streambuf object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.capacity [*capacity]]]
+ [Get the current capacity of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.commit [*commit]]]
+ [Move characters from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.max_size [*max_size]]]
+ [Get the maximum size of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.overflow [*overflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.reserve [*reserve]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.underflow [*underflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+]
+
+The `basic_streambuf` class is derived from `std::streambuf` to associate the streambuf's input and output sequences with one or more character arrays. These character arrays are internal to the `basic_streambuf` object, but direct access to the array elements is provided to permit them to be used efficiently with I/O operations. Characters written to the output sequence of a `basic_streambuf` object are appended to the input sequence of the same object.
+
+The `basic_streambuf` class's public interface is intended to permit the following implementation strategies:
+
+
+* A single contiguous character array, which is reallocated as necessary to accommodate changes in the size of the character sequence. This is the implementation approach currently used in Asio.
+
+
+* A sequence of one or more character arrays, where each array is of the same size. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+
+* A sequence of one or more character arrays of varying sizes. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+The constructor for [link asio.reference.basic_streambuf `basic_streambuf`] accepts a `size_t` argument specifying the maximum of the sum of the sizes of the input sequence and output sequence. During the lifetime of the `basic_streambuf` object, the following invariant holds:
+
+ size() <= max_size()
+
+
+Any member function that would, if successful, cause the invariant to be violated shall throw an exception of class `std::length_error`.
+
+The constructor for `basic_streambuf` takes an Allocator argument. A copy of this argument is used for any memory allocation performed, by the constructor and by all member functions, during the lifetime of each `basic_streambuf` object.
+
+
+[heading Examples]
+
+Writing directly from an streambuf to a socket:
+
+ asio::streambuf b;
+ std::ostream os(&b);
+ os << "Hello, World!\n";
+
+ // try sending some data in input sequence
+ size_t n = sock.send(b.data());
+
+ b.consume(n); // sent data is removed from input sequence
+
+
+
+
+Reading from a socket directly into a streambuf:
+
+ asio::streambuf b;
+
+ // reserve 512 bytes in output sequence
+ asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
+
+ size_t n = sock.receive(bufs);
+
+ // received data is "committed" from output sequence to input sequence
+ b.commit(n);
+
+ std::istream is(&b);
+ std::string s;
+ is >> s;
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:consume basic_streambuf_ref::consume]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.consume..consume..basic_streambuf_ref]
+Remove characters from the input sequence.
+
+
+ void consume(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:data basic_streambuf_ref::data]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.data..data..basic_streambuf_ref]
+Get a list of buffers that represents the input sequence.
+
+
+ const_buffers_type data() const;
+
+
+
+[endsect]
+
+
+
+[section:max_size basic_streambuf_ref::max_size]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.max_size..max_size..basic_streambuf_ref]
+Get the maximum size of the dynamic buffer.
+
+
+ std::size_t max_size() const;
+
+
+
+[endsect]
+
+
+
+[section:mutable_buffers_type basic_streambuf_ref::mutable_buffers_type]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.mutable_buffers_type..mutable_buffers_type..basic_streambuf_ref]
+The type used to represent the output sequence as a list of buffers.
+
+
+ typedef basic_streambuf< Allocator >::mutable_buffers_type mutable_buffers_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_streambuf.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_streambuf.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.basic_streambuf [*basic_streambuf]]]
+ [Construct a basic_streambuf object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.capacity [*capacity]]]
+ [Get the current capacity of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.commit [*commit]]]
+ [Move characters from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.max_size [*max_size]]]
+ [Get the maximum size of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.overflow [*overflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.reserve [*reserve]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.underflow [*underflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+]
+
+The `basic_streambuf` class is derived from `std::streambuf` to associate the streambuf's input and output sequences with one or more character arrays. These character arrays are internal to the `basic_streambuf` object, but direct access to the array elements is provided to permit them to be used efficiently with I/O operations. Characters written to the output sequence of a `basic_streambuf` object are appended to the input sequence of the same object.
+
+The `basic_streambuf` class's public interface is intended to permit the following implementation strategies:
+
+
+* A single contiguous character array, which is reallocated as necessary to accommodate changes in the size of the character sequence. This is the implementation approach currently used in Asio.
+
+
+* A sequence of one or more character arrays, where each array is of the same size. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+
+* A sequence of one or more character arrays of varying sizes. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+The constructor for [link asio.reference.basic_streambuf `basic_streambuf`] accepts a `size_t` argument specifying the maximum of the sum of the sizes of the input sequence and output sequence. During the lifetime of the `basic_streambuf` object, the following invariant holds:
+
+ size() <= max_size()
+
+
+Any member function that would, if successful, cause the invariant to be violated shall throw an exception of class `std::length_error`.
+
+The constructor for `basic_streambuf` takes an Allocator argument. A copy of this argument is used for any memory allocation performed, by the constructor and by all member functions, during the lifetime of each `basic_streambuf` object.
+
+
+[heading Examples]
+
+Writing directly from an streambuf to a socket:
+
+ asio::streambuf b;
+ std::ostream os(&b);
+ os << "Hello, World!\n";
+
+ // try sending some data in input sequence
+ size_t n = sock.send(b.data());
+
+ b.consume(n); // sent data is removed from input sequence
+
+
+
+
+Reading from a socket directly into a streambuf:
+
+ asio::streambuf b;
+
+ // reserve 512 bytes in output sequence
+ asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
+
+ size_t n = sock.receive(bufs);
+
+ // received data is "committed" from output sequence to input sequence
+ b.commit(n);
+
+ std::istream is(&b);
+ std::string s;
+ is >> s;
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:prepare basic_streambuf_ref::prepare]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.prepare..prepare..basic_streambuf_ref]
+Get a list of buffers that represents the output sequence, with the given size.
+
+
+ mutable_buffers_type prepare(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size basic_streambuf_ref::size]
+
+[indexterm2 asio.indexterm.basic_streambuf_ref.size..size..basic_streambuf_ref]
+Get the size of the input sequence.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_waitable_timer basic_waitable_timer]
+
+
+Provides waitable timer functionality.
+
+
+ template<
+ typename Clock,
+ typename ``[link asio.reference.WaitTraits WaitTraits]``>
+ class basic_waitable_timer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.duration [*duration]]]
+ [The duration type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.time_point [*time_point]]]
+ [The time point type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.traits_type [*traits_type]]]
+ [The wait traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_waitable_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.basic_waitable_timer [*basic_waitable_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_after [*expires_after]]]
+ [Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time.
+
+ (Deprecated: Use non-error_code overload.) Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expiry [*expiry]]]
+ [Get the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer._basic_waitable_timer [*~basic_waitable_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_waitable_timer `basic_waitable_timer`] class template provides the ability to perform a blocking or asynchronous wait for a timer to expire.
+
+A waitable 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 one of the [link asio.reference.steady_timer `steady_timer`], [link asio.reference.system_timer `system_timer`] or [link asio.reference.high_resolution_timer `high_resolution_timer`] typedefs.
+
+
+[heading Remarks]
+
+This waitable timer functionality is for use with the C++11 standard library's `<chrono>` facility, or with the Boost.Chrono library.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait (C++11):
+
+ // Construct a timer without setting an expiry time.
+ asio::steady_timer timer(io_context);
+
+ // Set an expiry time relative to now.
+ timer.expires_after(std::chrono::seconds(5));
+
+ // Wait for the timer to expire.
+ timer.wait();
+
+
+
+
+
+Performing an asynchronous wait (C++11):
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::steady_timer timer(io_context,
+ std::chrono::steady_clock::now() + std::chrono::seconds(60));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading Changing an active waitable 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:
+
+
+
+ void on_some_event()
+ {
+ if (my_timer.expires_after(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.
+ }
+ }
+
+
+
+
+
+* The `asio::basic_waitable_timer::expires_after()` 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_wait basic_waitable_timer::async_wait]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.async_wait..async_wait..basic_waitable_timer]
+Start an asynchronous wait on the timer.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ WaitHandler && handler);
+
+
+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:
+
+
+* The timer has expired.
+
+
+* The timer was cancelled, in which case the handler is passed the error code `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[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:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:basic_waitable_timer basic_waitable_timer::basic_waitable_timer]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.basic_waitable_timer..basic_waitable_timer..basic_waitable_timer]
+Constructor.
+
+
+ explicit ``[link asio.reference.basic_waitable_timer.basic_waitable_timer.overload1 basic_waitable_timer]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.basic_waitable_timer.overload1 more...]]``
+
+
+Constructor to set a particular expiry time as an absolute time.
+
+
+ ``[link asio.reference.basic_waitable_timer.basic_waitable_timer.overload2 basic_waitable_timer]``(
+ asio::io_context & io_context,
+ const time_point & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.basic_waitable_timer.overload2 more...]]``
+
+
+Constructor to set a particular expiry time relative to now.
+
+
+ ``[link asio.reference.basic_waitable_timer.basic_waitable_timer.overload3 basic_waitable_timer]``(
+ asio::io_context & io_context,
+ const duration & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.basic_waitable_timer.overload3 more...]]``
+
+
+Move-construct a [link asio.reference.basic_waitable_timer `basic_waitable_timer`] from another.
+
+
+ ``[link asio.reference.basic_waitable_timer.basic_waitable_timer.overload4 basic_waitable_timer]``(
+ basic_waitable_timer && other);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.basic_waitable_timer.overload4 more...]]``
+
+
+[section:overload1 basic_waitable_timer::basic_waitable_timer (1 of 4 overloads)]
+
+
+Constructor.
+
+
+ basic_waitable_timer(
+ asio::io_context & io_context);
+
+
+This constructor creates a timer without setting an expiry time. The `expires_at()` or `expires_after()` functions must be called to set an expiry time before the timer can be waited on.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::basic_waitable_timer (2 of 4 overloads)]
+
+
+Constructor to set a particular expiry time as an absolute time.
+
+
+ basic_waitable_timer(
+ asio::io_context & io_context,
+ const time_point & expiry_time);
+
+
+This constructor creates a timer and sets the expiry time.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer.]]
+
+[[expiry_time][The expiry time to be used for the timer, expressed as an absolute time. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 basic_waitable_timer::basic_waitable_timer (3 of 4 overloads)]
+
+
+Constructor to set a particular expiry time relative to now.
+
+
+ basic_waitable_timer(
+ asio::io_context & io_context,
+ const duration & expiry_time);
+
+
+This constructor creates a timer and sets the expiry time.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the timer will use to dispatch handlers for any asynchronous operations performed on the timer.]]
+
+[[expiry_time][The expiry time to be used for the timer, relative to now. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 basic_waitable_timer::basic_waitable_timer (4 of 4 overloads)]
+
+
+Move-construct a [link asio.reference.basic_waitable_timer `basic_waitable_timer`] from another.
+
+
+ basic_waitable_timer(
+ basic_waitable_timer && other);
+
+
+This constructor moves a timer from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_waitable_timer `basic_waitable_timer`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_waitable_timer(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:cancel basic_waitable_timer::cancel]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.cancel..cancel..basic_waitable_timer]
+Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.cancel.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.cancel.overload2 more...]]``
+
+
+[section:overload1 basic_waitable_timer::cancel (1 of 2 overloads)]
+
+
+Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t cancel();
+
+
+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.
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::cancel (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Cancel any asynchronous operations that are waiting on the timer.
+
+
+ std::size_t cancel(
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:cancel_one basic_waitable_timer::cancel_one]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.cancel_one..cancel_one..basic_waitable_timer]
+Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.cancel_one.overload1 cancel_one]``();
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.cancel_one.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.cancel_one.overload2 cancel_one]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.cancel_one.overload2 more...]]``
+
+
+[section:overload1 basic_waitable_timer::cancel_one (1 of 2 overloads)]
+
+
+Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t cancel_one();
+
+
+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.
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled. That is, either 0 or 1.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel_one()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::cancel_one (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Cancels one asynchronous operation that is waiting on the timer.
+
+
+ std::size_t cancel_one(
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled. That is, either 0 or 1.
+
+
+[heading Remarks]
+
+If the timer has already expired when `cancel_one()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:clock_type basic_waitable_timer::clock_type]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.clock_type..clock_type..basic_waitable_timer]
+The clock type.
+
+
+ typedef Clock clock_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:duration basic_waitable_timer::duration]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.duration..duration..basic_waitable_timer]
+The duration type of the clock.
+
+
+ typedef clock_type::duration duration;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type basic_waitable_timer::executor_type]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.executor_type..executor_type..basic_waitable_timer]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:expires_after basic_waitable_timer::expires_after]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.expires_after..expires_after..basic_waitable_timer]
+Set the timer's expiry time relative to now.
+
+
+ std::size_t expires_after(
+ const duration & expiry_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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_after()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[section:expires_at basic_waitable_timer::expires_at]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.expires_at..expires_at..basic_waitable_timer]
+(Deprecated: Use `expiry()`.) Get the timer's expiry time as an absolute time.
+
+
+ time_point ``[link asio.reference.basic_waitable_timer.expires_at.overload1 expires_at]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_at.overload1 more...]]``
+
+
+Set the timer's expiry time as an absolute time.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.expires_at.overload2 expires_at]``(
+ const time_point & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_at.overload2 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Set the timer's expiry time as an absolute time.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.expires_at.overload3 expires_at]``(
+ const time_point & expiry_time,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_at.overload3 more...]]``
+
+
+[section:overload1 basic_waitable_timer::expires_at (1 of 3 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the timer's expiry time as an absolute time.
+
+
+ time_point expires_at() const;
+
+
+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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::expires_at (2 of 3 overloads)]
+
+
+Set the timer's expiry time as an absolute time.
+
+
+ std::size_t expires_at(
+ const time_point & expiry_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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_at()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload3 basic_waitable_timer::expires_at (3 of 3 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Set the timer's expiry time as an absolute time.
+
+
+ std::size_t expires_at(
+ const time_point & expiry_time,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_at()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:expires_from_now basic_waitable_timer::expires_from_now]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.expires_from_now..expires_from_now..basic_waitable_timer]
+(Deprecated: Use `expiry()`.) Get the timer's expiry time relative to now.
+
+
+ duration ``[link asio.reference.basic_waitable_timer.expires_from_now.overload1 expires_from_now]``() const;
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_from_now.overload1 more...]]``
+
+
+(Deprecated: Use `expires_after()`.) Set the timer's expiry time relative to now.
+
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.expires_from_now.overload2 expires_from_now]``(
+ const duration & expiry_time);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_from_now.overload2 more...]]``
+
+ std::size_t ``[link asio.reference.basic_waitable_timer.expires_from_now.overload3 expires_from_now]``(
+ const duration & expiry_time,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.expires_from_now.overload3 more...]]``
+
+
+[section:overload1 basic_waitable_timer::expires_from_now (1 of 3 overloads)]
+
+
+(Deprecated: Use `expiry()`.) Get the timer's expiry time relative to now.
+
+
+ duration expires_from_now() const;
+
+
+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.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::expires_from_now (2 of 3 overloads)]
+
+
+(Deprecated: Use `expires_after()`.) Set the timer's expiry time relative to now.
+
+
+ std::size_t expires_from_now(
+ const duration & expiry_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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_from_now()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload3 basic_waitable_timer::expires_from_now (3 of 3 overloads)]
+
+
+(Deprecated: Use `expires_after()`.) Set the timer's expiry time relative to now.
+
+
+ std::size_t expires_from_now(
+ const duration & expiry_time,
+ asio::error_code & ec);
+
+
+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.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[expiry_time][The expiry time to be used for the timer.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of asynchronous operations that were cancelled.
+
+
+[heading Remarks]
+
+If the timer has already expired when `expires_from_now()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:expiry basic_waitable_timer::expiry]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.expiry..expiry..basic_waitable_timer]
+Get the timer's expiry time as an absolute time.
+
+
+ time_point expiry() const;
+
+
+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.
+
+
+[endsect]
+
+
+
+[section:get_executor basic_waitable_timer::get_executor]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.get_executor..get_executor..basic_waitable_timer]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context basic_waitable_timer::get_io_context]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.get_io_context..get_io_context..basic_waitable_timer]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service basic_waitable_timer::get_io_service]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.get_io_service..get_io_service..basic_waitable_timer]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ basic_waitable_timer::operator=]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.operator_eq_..operator=..basic_waitable_timer]
+Move-assign a [link asio.reference.basic_waitable_timer `basic_waitable_timer`] from another.
+
+
+ basic_waitable_timer & operator=(
+ basic_waitable_timer && other);
+
+
+This assignment operator moves a timer from one object to another. Cancels any outstanding asynchronous operations associated with the target object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.basic_waitable_timer `basic_waitable_timer`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_waitable_timer(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:time_point basic_waitable_timer::time_point]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.time_point..time_point..basic_waitable_timer]
+The time point type of the clock.
+
+
+ typedef clock_type::time_point time_point;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:traits_type basic_waitable_timer::traits_type]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.traits_type..traits_type..basic_waitable_timer]
+The wait traits type.
+
+
+ typedef WaitTraits traits_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/basic_waitable_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:wait basic_waitable_timer::wait]
+
+[indexterm2 asio.indexterm.basic_waitable_timer.wait..wait..basic_waitable_timer]
+Perform a blocking wait on the timer.
+
+
+ void ``[link asio.reference.basic_waitable_timer.wait.overload1 wait]``();
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.wait.overload1 more...]]``
+
+ void ``[link asio.reference.basic_waitable_timer.wait.overload2 wait]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.basic_waitable_timer.wait.overload2 more...]]``
+
+
+[section:overload1 basic_waitable_timer::wait (1 of 2 overloads)]
+
+
+Perform a blocking wait on the timer.
+
+
+ void wait();
+
+
+This function is used to wait for the timer to expire. This function blocks and does not return until the timer has expired.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 basic_waitable_timer::wait (2 of 2 overloads)]
+
+
+Perform a blocking wait on the timer.
+
+
+ void wait(
+ asio::error_code & ec);
+
+
+This function is used to wait for the timer to expire. This function blocks and does not return until the timer has expired.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_basic_waitable_timer basic_waitable_timer::~basic_waitable_timer]
+
+[indexterm2 asio.indexterm.basic_waitable_timer._basic_waitable_timer..~basic_waitable_timer..basic_waitable_timer]
+Destroys the timer.
+
+
+ ~basic_waitable_timer();
+
+
+This function destroys the timer, cancelling any outstanding asynchronous wait operations associated with the timer as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:basic_yield_context basic_yield_context]
+
+
+Context object the represents the currently executing coroutine.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ class basic_yield_context
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_yield_context.callee_type [*callee_type]]]
+ [The coroutine callee type, used by the implementation. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_yield_context.caller_type [*caller_type]]]
+ [The coroutine caller type, used by the implementation. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_yield_context.basic_yield_context [*basic_yield_context]]]
+ [Construct a yield context to represent the specified coroutine.
+
+ Construct a yield context from another yield context type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_yield_context.operator_lb__rb_ [*operator\[\]]]]
+ [Return a yield context that sets the specified error_code. ]
+ ]
+
+]
+
+The [link asio.reference.basic_yield_context `basic_yield_context`] class is used to represent the currently executing stackful coroutine. A [link asio.reference.basic_yield_context `basic_yield_context`] may be passed as a handler to an asynchronous operation. For example:
+
+
+
+ template <typename Handler>
+ void my_coroutine(basic_yield_context<Handler> yield)
+ {
+ ...
+ std::size_t n = my_socket.async_read_some(buffer, yield);
+ ...
+ }
+
+
+
+
+The initiating function (async\_read\_some in the above example) suspends the current coroutine. The coroutine is resumed when the asynchronous operation completes, and the result of the operation is returned.
+
+[heading Requirements]
+
+['Header: ][^asio/spawn.hpp]
+
+['Convenience header: ]None
+
+[section:basic_yield_context basic_yield_context::basic_yield_context]
+
+[indexterm2 asio.indexterm.basic_yield_context.basic_yield_context..basic_yield_context..basic_yield_context]
+Construct a yield context to represent the specified coroutine.
+
+
+ ``[link asio.reference.basic_yield_context.basic_yield_context.overload1 basic_yield_context]``(
+ const detail::weak_ptr< callee_type > & coro,
+ caller_type & ca,
+ Handler & handler);
+ `` [''''&raquo;''' [link asio.reference.basic_yield_context.basic_yield_context.overload1 more...]]``
+
+
+Construct a yield context from another yield context type.
+
+
+ template<
+ typename OtherHandler>
+ ``[link asio.reference.basic_yield_context.basic_yield_context.overload2 basic_yield_context]``(
+ const basic_yield_context< OtherHandler > & other);
+ `` [''''&raquo;''' [link asio.reference.basic_yield_context.basic_yield_context.overload2 more...]]``
+
+
+[section:overload1 basic_yield_context::basic_yield_context (1 of 2 overloads)]
+
+
+Construct a yield context to represent the specified coroutine.
+
+
+ basic_yield_context(
+ const detail::weak_ptr< callee_type > & coro,
+ caller_type & ca,
+ Handler & handler);
+
+
+Most applications do not need to use this constructor. Instead, the `spawn()` function passes a yield context as an argument to the coroutine function.
+
+
+[endsect]
+
+
+
+[section:overload2 basic_yield_context::basic_yield_context (2 of 2 overloads)]
+
+
+Construct a yield context from another yield context type.
+
+
+ template<
+ typename OtherHandler>
+ basic_yield_context(
+ const basic_yield_context< OtherHandler > & other);
+
+
+Requires that OtherHandler be convertible to Handler.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:callee_type basic_yield_context::callee_type]
+
+[indexterm2 asio.indexterm.basic_yield_context.callee_type..callee_type..basic_yield_context]
+The coroutine callee type, used by the implementation.
+
+
+ typedef implementation_defined callee_type;
+
+
+
+When using Boost.Coroutine v1, this type is:
+
+ typename coroutine<void()>
+
+
+When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
+
+ push_coroutine<void>
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/spawn.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+
+[section:caller_type basic_yield_context::caller_type]
+
+[indexterm2 asio.indexterm.basic_yield_context.caller_type..caller_type..basic_yield_context]
+The coroutine caller type, used by the implementation.
+
+
+ typedef implementation_defined caller_type;
+
+
+
+When using Boost.Coroutine v1, this type is:
+
+ typename coroutine<void()>::caller_type
+
+
+When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
+
+ pull_coroutine<void>
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/spawn.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+
+[section:operator_lb__rb_ basic_yield_context::operator\[\]]
+
+[indexterm2 asio.indexterm.basic_yield_context.operator_lb__rb_..operator\[\]..basic_yield_context]
+Return a yield context that sets the specified [link asio.reference.error_code `error_code`].
+
+
+ basic_yield_context operator[](
+ asio::error_code & ec) const;
+
+
+By default, when a yield context is used with an asynchronous operation, a non-success [link asio.reference.error_code `error_code`] is converted to [link asio.reference.system_error `system_error`] and thrown. This operator may be used to specify an [link asio.reference.error_code `error_code`] object that should instead be set with the asynchronous operation's result. For example:
+
+
+
+ template <typename Handler>
+ void my_coroutine(basic_yield_context<Handler> yield)
+ {
+ ...
+ std::size_t n = my_socket.async_read_some(buffer, yield[ec]);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ ...
+ }
+
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:bind_executor bind_executor]
+
+[indexterm1 asio.indexterm.bind_executor..bind_executor]
+Associate an object of type `T` with an executor of type `Executor`.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename T>
+ executor_binder< typename decay< T >::type, Executor > ``[link asio.reference.bind_executor.overload1 bind_executor]``(
+ const Executor & ex,
+ T && t,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.bind_executor.overload1 more...]]``
+
+ template<
+ typename ExecutionContext,
+ typename T>
+ executor_binder< typename decay< T >::type, typename ExecutionContext::executor_type > ``[link asio.reference.bind_executor.overload2 bind_executor]``(
+ ExecutionContext & ctx,
+ T && t,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.bind_executor.overload2 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 bind_executor (1 of 2 overloads)]
+
+
+Associate an object of type `T` with an executor of type `Executor`.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename T>
+ executor_binder< typename decay< T >::type, Executor > bind_executor(
+ const Executor & ex,
+ T && t,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload2 bind_executor (2 of 2 overloads)]
+
+
+Associate an object of type `T` with an execution context's executor.
+
+
+ template<
+ typename ExecutionContext,
+ typename T>
+ executor_binder< typename decay< T >::type, typename ExecutionContext::executor_type > bind_executor(
+ ExecutionContext & ctx,
+ T && t,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffer buffer]
+
+[indexterm1 asio.indexterm.buffer..buffer]
+The `asio::buffer` function is used to create a buffer object to represent raw memory, an array of POD elements, a vector of POD elements, or a std::string.
+
+
+ mutable_buffer ``[link asio.reference.buffer.overload1 buffer]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload1 more...]]``
+
+ mutable_buffer ``[link asio.reference.buffer.overload2 buffer]``(
+ const mutable_buffer & b,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload2 more...]]``
+
+ const_buffer ``[link asio.reference.buffer.overload3 buffer]``(
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload3 more...]]``
+
+ const_buffer ``[link asio.reference.buffer.overload4 buffer]``(
+ const const_buffer & b,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload4 more...]]``
+
+ mutable_buffer ``[link asio.reference.buffer.overload5 buffer]``(
+ void * data,
+ std::size_t size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload5 more...]]``
+
+ const_buffer ``[link asio.reference.buffer.overload6 buffer]``(
+ const void * data,
+ std::size_t size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload6 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload7 buffer]``(
+ PodType (&data)[N]);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload7 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload8 buffer]``(
+ PodType (&data)[N],
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload8 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload9 buffer]``(
+ const PodType (&data)[N]);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload9 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload10 buffer]``(
+ const PodType (&data)[N],
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload10 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload11 buffer]``(
+ boost::array< PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload11 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload12 buffer]``(
+ boost::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload12 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload13 buffer]``(
+ boost::array< const PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload13 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload14 buffer]``(
+ boost::array< const PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload14 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload15 buffer]``(
+ const boost::array< PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload15 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload16 buffer]``(
+ const boost::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload16 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload17 buffer]``(
+ std::array< PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload17 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer ``[link asio.reference.buffer.overload18 buffer]``(
+ std::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload18 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload19 buffer]``(
+ std::array< const PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload19 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload20 buffer]``(
+ std::array< const PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload20 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload21 buffer]``(
+ const std::array< PodType, N > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload21 more...]]``
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer ``[link asio.reference.buffer.overload22 buffer]``(
+ const std::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload22 more...]]``
+
+ template<
+ typename PodType,
+ typename Allocator>
+ mutable_buffer ``[link asio.reference.buffer.overload23 buffer]``(
+ std::vector< PodType, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload23 more...]]``
+
+ template<
+ typename PodType,
+ typename Allocator>
+ mutable_buffer ``[link asio.reference.buffer.overload24 buffer]``(
+ std::vector< PodType, Allocator > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload24 more...]]``
+
+ template<
+ typename PodType,
+ typename Allocator>
+ const_buffer ``[link asio.reference.buffer.overload25 buffer]``(
+ const std::vector< PodType, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload25 more...]]``
+
+ template<
+ typename PodType,
+ typename Allocator>
+ const_buffer ``[link asio.reference.buffer.overload26 buffer]``(
+ const std::vector< PodType, Allocator > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload26 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ mutable_buffer ``[link asio.reference.buffer.overload27 buffer]``(
+ std::basic_string< Elem, Traits, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload27 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ mutable_buffer ``[link asio.reference.buffer.overload28 buffer]``(
+ std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload28 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ const_buffer ``[link asio.reference.buffer.overload29 buffer]``(
+ const std::basic_string< Elem, Traits, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload29 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ const_buffer ``[link asio.reference.buffer.overload30 buffer]``(
+ const std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload30 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits>
+ const_buffer ``[link asio.reference.buffer.overload31 buffer]``(
+ basic_string_view< Elem, Traits > data);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload31 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits>
+ const_buffer ``[link asio.reference.buffer.overload32 buffer]``(
+ basic_string_view< Elem, Traits > data,
+ std::size_t max_size_in_bytes);
+ `` [''''&raquo;''' [link asio.reference.buffer.overload32 more...]]``
+
+A buffer object represents a contiguous region of memory as a 2-tuple consisting of a pointer and size in bytes. A tuple of the form `{void*, size_t}` specifies a mutable (modifiable) region of memory. Similarly, a tuple of the form `{const void*, size_t}` specifies a const (non-modifiable) region of memory. These two forms correspond to the classes [link asio.reference.mutable_buffer `mutable_buffer`] and [link asio.reference.const_buffer `const_buffer`], respectively. To mirror C++'s conversion rules, a [link asio.reference.mutable_buffer `mutable_buffer`] is implicitly convertible to a [link asio.reference.const_buffer `const_buffer`], and the opposite conversion is not permitted.
+
+The simplest use case involves reading or writing a single buffer of a specified size:
+
+
+
+ sock.send(asio::buffer(data, size));
+
+
+
+
+In the above example, the return value of `asio::buffer` meets the requirements of the ConstBufferSequence concept so that it may be directly passed to the socket's write function. A buffer created for modifiable memory also meets the requirements of the MutableBufferSequence concept.
+
+An individual buffer may be created from a builtin array, std::vector, std::array or boost::array of POD elements. This helps prevent buffer overruns by automatically determining the size of the buffer:
+
+
+
+ char d1[128];
+ size_t bytes_transferred = sock.receive(asio::buffer(d1));
+
+ std::vector<char> d2(128);
+ bytes_transferred = sock.receive(asio::buffer(d2));
+
+ std::array<char, 128> d3;
+ bytes_transferred = sock.receive(asio::buffer(d3));
+
+ boost::array<char, 128> d4;
+ bytes_transferred = sock.receive(asio::buffer(d4));
+
+
+
+
+In all three cases above, the buffers created are exactly 128 bytes long. Note that a vector is ['never] automatically resized when creating or using a buffer. The buffer size is determined using the vector's `size()` member function, and not its capacity.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+ asio::const_buffer b2 = ...;
+ std::size_t s2 = b2.size();
+ const void* p2 = b2.data();
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+For convenience, a [link asio.reference.buffer_size `buffer_size`] function is provided that works with both buffers and buffer sequences (that is, types meeting the ConstBufferSequence or MutableBufferSequence type requirements). In this case, the function returns the total size of all buffers in the sequence.
+
+
+[heading Buffer Copying]
+
+
+
+The [link asio.reference.buffer_copy `buffer_copy`] function may be used to copy raw bytes between individual buffers and buffer sequences.
+
+In particular, when used with the [link asio.reference.buffer_size `buffer_size`] function, the [link asio.reference.buffer_copy `buffer_copy`] function can be used to linearise a sequence of buffers. For example:
+
+
+
+ vector<const_buffer> buffers = ...;
+
+ vector<unsigned char> data(asio::buffer_size(buffers));
+ asio::buffer_copy(asio::buffer(data), buffers);
+
+
+
+
+Note that [link asio.reference.buffer_copy `buffer_copy`] is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions.
+
+
+[heading Buffer Invalidation]
+
+
+
+A buffer object does not have any ownership of the memory it refers to. It is the responsibility of the application to ensure the memory region remains valid until it is no longer required for an I/O operation. When the memory is no longer available, the buffer is said to have been invalidated.
+
+For the `asio::buffer` overloads that accept an argument of type std::vector, the buffer objects returned are invalidated by any vector operation that also invalidates all references, pointers and iterators referring to the elements in the sequence (C++ Std, 23.2.4)
+
+For the `asio::buffer` overloads that accept an argument of type std::basic\_string, the buffer objects returned are invalidated according to the rules defined for invalidation of references, pointers and iterators referring to elements of the sequence (C++ Std, 21.3).
+
+
+[heading Buffer Arithmetic]
+
+
+
+Buffer objects may be manipulated using simple arithmetic in a safe way which helps prevent buffer overruns. Consider an array initialised as follows:
+
+
+
+ boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' };
+
+
+
+
+A buffer object `b1` created using:
+
+
+
+ b1 = asio::buffer(a);
+
+
+
+
+represents the entire array, `{ 'a', 'b', 'c', 'd', 'e' }`. An optional second argument to the `asio::buffer` function may be used to limit the size, in bytes, of the buffer:
+
+
+
+ b2 = asio::buffer(a, 3);
+
+
+
+
+such that `b2` represents the data `{ 'a', 'b', 'c' }`. Even if the size argument exceeds the actual size of the array, the size of the buffer object created will be limited to the array size.
+
+An offset may be applied to an existing buffer to create a new one:
+
+
+
+ b3 = b1 + 2;
+
+
+
+
+where `b3` will set to represent `{ 'c', 'd', 'e' }`. If the offset exceeds the size of the existing buffer, the newly created buffer will be empty.
+
+Both an offset and size may be specified to create a buffer that corresponds to a specific range of bytes within an existing buffer:
+
+
+
+ b4 = asio::buffer(b1 + 1, 3);
+
+
+
+
+so that `b4` will refer to the bytes `{ 'b', 'c', 'd' }`.
+
+
+[heading Buffers and Scatter-Gather I/O]
+
+
+
+To read or write using multiple buffers (i.e. scatter-gather I/O), multiple buffer objects may be assigned into a container that supports the MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
+
+
+
+ char d1[128];
+ std::vector<char> d2(128);
+ boost::array<char, 128> d3;
+
+ boost::array<mutable_buffer, 3> bufs1 = {
+ asio::buffer(d1),
+ asio::buffer(d2),
+ asio::buffer(d3) };
+ bytes_transferred = sock.receive(bufs1);
+
+ std::vector<const_buffer> bufs2;
+ bufs2.push_back(asio::buffer(d1));
+ bufs2.push_back(asio::buffer(d2));
+ bufs2.push_back(asio::buffer(d3));
+ bytes_transferred = sock.send(bufs2);
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 buffer (1 of 32 overloads)]
+
+
+Create a new modifiable buffer from an existing buffer.
+
+
+ mutable_buffer buffer(
+ const mutable_buffer & b);
+
+
+
+[heading Return Value]
+
+`mutable_buffer(b)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffer (2 of 32 overloads)]
+
+
+Create a new modifiable buffer from an existing buffer.
+
+
+ mutable_buffer buffer(
+ const mutable_buffer & b,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ b.data(),
+ min(b.size(), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 buffer (3 of 32 overloads)]
+
+
+Create a new non-modifiable buffer from an existing buffer.
+
+
+ const_buffer buffer(
+ const const_buffer & b);
+
+
+
+[heading Return Value]
+
+`const_buffer(b)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 buffer (4 of 32 overloads)]
+
+
+Create a new non-modifiable buffer from an existing buffer.
+
+
+ const_buffer buffer(
+ const const_buffer & b,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ b.data(),
+ min(b.size(), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 buffer (5 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given memory range.
+
+
+ mutable_buffer buffer(
+ void * data,
+ std::size_t size_in_bytes);
+
+
+
+[heading Return Value]
+
+`mutable_buffer(data, size_in_bytes)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 buffer (6 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given memory range.
+
+
+ const_buffer buffer(
+ const void * data,
+ std::size_t size_in_bytes);
+
+
+
+[heading Return Value]
+
+`const_buffer(data, size_in_bytes)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 buffer (7 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ PodType (&data)[N]);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ static_cast<void*>(data),
+ N * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 buffer (8 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ PodType (&data)[N],
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ static_cast<void*>(data),
+ min(N * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 buffer (9 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const PodType (&data)[N]);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ static_cast<const void*>(data),
+ N * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 buffer (10 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const PodType (&data)[N],
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ static_cast<const void*>(data),
+ min(N * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 buffer (11 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ boost::array< PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 buffer (12 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ boost::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload13 buffer (13 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ boost::array< const PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload14 buffer (14 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ boost::array< const PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload15 buffer (15 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const boost::array< PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload16 buffer (16 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const boost::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload17 buffer (17 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ std::array< PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload18 buffer (18 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ mutable_buffer buffer(
+ std::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload19 buffer (19 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ std::array< const PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload20 buffer (20 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ std::array< const PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload21 buffer (21 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const std::array< PodType, N > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ data.size() * sizeof(PodType));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload22 buffer (22 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD array.
+
+
+ template<
+ typename PodType,
+ std::size_t N>
+ const_buffer buffer(
+ const std::array< PodType, N > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload23 buffer (23 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD vector.
+
+
+ template<
+ typename PodType,
+ typename Allocator>
+ mutable_buffer buffer(
+ std::vector< PodType, Allocator > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.size() ? &data[0] : 0,
+ data.size() * sizeof(PodType));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any vector operation that would also invalidate iterators.
+
+
+
+
+[endsect]
+
+
+
+[section:overload24 buffer (24 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given POD vector.
+
+
+ template<
+ typename PodType,
+ typename Allocator>
+ mutable_buffer buffer(
+ std::vector< PodType, Allocator > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.size() ? &data[0] : 0,
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any vector operation that would also invalidate iterators.
+
+
+
+
+[endsect]
+
+
+
+[section:overload25 buffer (25 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD vector.
+
+
+ template<
+ typename PodType,
+ typename Allocator>
+ const_buffer buffer(
+ const std::vector< PodType, Allocator > & data);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.size() ? &data[0] : 0,
+ data.size() * sizeof(PodType));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any vector operation that would also invalidate iterators.
+
+
+
+
+[endsect]
+
+
+
+[section:overload26 buffer (26 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given POD vector.
+
+
+ template<
+ typename PodType,
+ typename Allocator>
+ const_buffer buffer(
+ const std::vector< PodType, Allocator > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.size() ? &data[0] : 0,
+ min(data.size() * sizeof(PodType), max_size_in_bytes));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any vector operation that would also invalidate iterators.
+
+
+
+
+[endsect]
+
+
+
+[section:overload27 buffer (27 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ mutable_buffer buffer(
+ std::basic_string< Elem, Traits, Allocator > & data);
+
+
+
+[heading Return Value]
+
+`mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(Elem))`.
+
+
+[heading Remarks]
+
+The buffer is invalidated by any non-const operation called on the given string object.
+
+
+
+
+[endsect]
+
+
+
+[section:overload28 buffer (28 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ mutable_buffer buffer(
+ std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.size() ? &data[0] : 0,
+ min(data.size() * sizeof(Elem), max_size_in_bytes));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any non-const operation called on the given string object.
+
+
+
+
+[endsect]
+
+
+
+[section:overload29 buffer (29 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ const_buffer buffer(
+ const std::basic_string< Elem, Traits, Allocator > & data);
+
+
+
+[heading Return Value]
+
+`const_buffer(data.data(), data.size() * sizeof(Elem))`.
+
+
+[heading Remarks]
+
+The buffer is invalidated by any non-const operation called on the given string object.
+
+
+
+
+[endsect]
+
+
+
+[section:overload30 buffer (30 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ const_buffer buffer(
+ const std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.const_buffer `const_buffer`] value equivalent to:
+
+ const_buffer(
+ data.data(),
+ min(data.size() * sizeof(Elem), max_size_in_bytes));
+
+
+
+
+
+[heading Remarks]
+
+The buffer is invalidated by any non-const operation called on the given string object.
+
+
+
+
+[endsect]
+
+
+
+[section:overload31 buffer (31 of 32 overloads)]
+
+
+Create a new modifiable buffer that represents the given string\_view.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ const_buffer buffer(
+ basic_string_view< Elem, Traits > data);
+
+
+
+[heading Return Value]
+
+`mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(Elem))`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload32 buffer (32 of 32 overloads)]
+
+
+Create a new non-modifiable buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ const_buffer buffer(
+ basic_string_view< Elem, Traits > data,
+ std::size_t max_size_in_bytes);
+
+
+
+[heading Return Value]
+
+A [link asio.reference.mutable_buffer `mutable_buffer`] value equivalent to:
+
+ mutable_buffer(
+ data.size() ? &data[0] : 0,
+ min(data.size() * sizeof(Elem), max_size_in_bytes));
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffer_cast buffer_cast]
+
+[indexterm1 asio.indexterm.buffer_cast..buffer_cast]
+(Deprecated: Use the `data()` member function.) The `asio::buffer_cast` function is used to obtain a pointer to the underlying memory region associated with a buffer.
+
+
+ template<
+ typename PointerToPodType>
+ PointerToPodType ``[link asio.reference.buffer_cast.overload1 buffer_cast]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_cast.overload1 more...]]``
+
+ template<
+ typename PointerToPodType>
+ PointerToPodType ``[link asio.reference.buffer_cast.overload2 buffer_cast]``(
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_cast.overload2 more...]]``
+
+
+[heading Examples:]
+
+
+
+To access the memory of a non-modifiable buffer, use:
+
+ asio::const_buffer b1 = ...;
+ const unsigned char* p1 = asio::buffer_cast<const unsigned char*>(b1);
+
+
+
+
+To access the memory of a modifiable buffer, use:
+
+ asio::mutable_buffer b2 = ...;
+ unsigned char* p2 = asio::buffer_cast<unsigned char*>(b2);
+
+
+
+
+The `asio::buffer_cast` function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 buffer_cast (1 of 2 overloads)]
+
+
+Cast a non-modifiable buffer to a specified pointer to POD type.
+
+
+ template<
+ typename PointerToPodType>
+ PointerToPodType buffer_cast(
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffer_cast (2 of 2 overloads)]
+
+
+Cast a non-modifiable buffer to a specified pointer to POD type.
+
+
+ template<
+ typename PointerToPodType>
+ PointerToPodType buffer_cast(
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffer_copy buffer_copy]
+
+[indexterm1 asio.indexterm.buffer_copy..buffer_copy]
+The `asio::buffer_copy` function is used to copy bytes from a source buffer (or buffer sequence) to a target buffer (or buffer sequence).
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffer_copy.overload1 buffer_copy]``(
+ const MutableBufferSequence & target,
+ const ConstBufferSequence & source);
+ `` [''''&raquo;''' [link asio.reference.buffer_copy.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffer_copy.overload2 buffer_copy]``(
+ const MutableBufferSequence & target,
+ const ConstBufferSequence & source,
+ std::size_t max_bytes_to_copy);
+ `` [''''&raquo;''' [link asio.reference.buffer_copy.overload2 more...]]``
+
+The `buffer_copy` function is available in two forms:
+
+
+* A 2-argument form: `buffer_copy(target, source)`
+
+
+* A 3-argument form: `buffer_copy(target, source, max_bytes_to_copy)`
+
+Both forms return the number of bytes actually copied. The number of bytes copied is the lesser of:
+
+
+* `buffer_size(target)`
+
+
+* `buffer_size(source)`
+
+
+* `If` specified, `max_bytes_to_copy`.
+
+This prevents buffer overflow, regardless of the buffer sizes used in the copy operation.
+
+Note that [link asio.reference.buffer_copy `buffer_copy`] is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 buffer_copy (1 of 2 overloads)]
+
+
+Copies bytes from a source buffer sequence to a target buffer sequence.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t buffer_copy(
+ const MutableBufferSequence & target,
+ const ConstBufferSequence & source);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
+
+[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes copied.
+
+
+[heading Remarks]
+
+The number of bytes copied is the lesser of:
+
+
+* `buffer_size(target)`
+
+
+* `buffer_size(source)`
+
+This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions.
+
+
+[endsect]
+
+
+
+[section:overload2 buffer_copy (2 of 2 overloads)]
+
+
+Copies a limited number of bytes from a source buffer sequence to a target buffer sequence.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t buffer_copy(
+ const MutableBufferSequence & target,
+ const ConstBufferSequence & source,
+ std::size_t max_bytes_to_copy);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
+
+[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
+
+[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes copied.
+
+
+[heading Remarks]
+
+The number of bytes copied is the lesser of:
+
+
+* `buffer_size(target)`
+
+
+* `buffer_size(source)`
+
+
+* `max_bytes_to_copy`
+
+This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffer_sequence_begin buffer_sequence_begin]
+
+[indexterm1 asio.indexterm.buffer_sequence_begin..buffer_sequence_begin]
+The `asio::buffer_sequence_begin` function returns an iterator pointing to the first element in a buffer sequence.
+
+
+ const mutable_buffer * ``[link asio.reference.buffer_sequence_begin.overload1 buffer_sequence_begin]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_begin.overload1 more...]]``
+
+ const const_buffer * ``[link asio.reference.buffer_sequence_begin.overload2 buffer_sequence_begin]``(
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_begin.overload2 more...]]``
+
+ template<
+ typename C>
+ auto ``[link asio.reference.buffer_sequence_begin.overload3 buffer_sequence_begin]``(
+ C & c);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_begin.overload3 more...]]``
+
+ template<
+ typename C>
+ auto ``[link asio.reference.buffer_sequence_begin.overload4 buffer_sequence_begin]``(
+ const C & c);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_begin.overload4 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 buffer_sequence_begin (1 of 4 overloads)]
+
+
+Get an iterator to the first element in a buffer sequence.
+
+
+ const mutable_buffer * buffer_sequence_begin(
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffer_sequence_begin (2 of 4 overloads)]
+
+
+Get an iterator to the first element in a buffer sequence.
+
+
+ const const_buffer * buffer_sequence_begin(
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+
+[section:overload3 buffer_sequence_begin (3 of 4 overloads)]
+
+
+Get an iterator to the first element in a buffer sequence.
+
+
+ template<
+ typename C>
+ auto buffer_sequence_begin(
+ C & c);
+
+
+
+[endsect]
+
+
+
+[section:overload4 buffer_sequence_begin (4 of 4 overloads)]
+
+
+Get an iterator to the first element in a buffer sequence.
+
+
+ template<
+ typename C>
+ auto buffer_sequence_begin(
+ const C & c);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffer_sequence_end buffer_sequence_end]
+
+[indexterm1 asio.indexterm.buffer_sequence_end..buffer_sequence_end]
+The `asio::buffer_sequence_end` function returns an iterator pointing to one past the end element in a buffer sequence.
+
+
+ const mutable_buffer * ``[link asio.reference.buffer_sequence_end.overload1 buffer_sequence_end]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_end.overload1 more...]]``
+
+ const const_buffer * ``[link asio.reference.buffer_sequence_end.overload2 buffer_sequence_end]``(
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_end.overload2 more...]]``
+
+ template<
+ typename C>
+ auto ``[link asio.reference.buffer_sequence_end.overload3 buffer_sequence_end]``(
+ C & c);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_end.overload3 more...]]``
+
+ template<
+ typename C>
+ auto ``[link asio.reference.buffer_sequence_end.overload4 buffer_sequence_end]``(
+ const C & c);
+ `` [''''&raquo;''' [link asio.reference.buffer_sequence_end.overload4 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 buffer_sequence_end (1 of 4 overloads)]
+
+
+Get an iterator to one past the end element in a buffer sequence.
+
+
+ const mutable_buffer * buffer_sequence_end(
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffer_sequence_end (2 of 4 overloads)]
+
+
+Get an iterator to one past the end element in a buffer sequence.
+
+
+ const const_buffer * buffer_sequence_end(
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+
+[section:overload3 buffer_sequence_end (3 of 4 overloads)]
+
+
+Get an iterator to one past the end element in a buffer sequence.
+
+
+ template<
+ typename C>
+ auto buffer_sequence_end(
+ C & c);
+
+
+
+[endsect]
+
+
+
+[section:overload4 buffer_sequence_end (4 of 4 overloads)]
+
+
+Get an iterator to one past the end element in a buffer sequence.
+
+
+ template<
+ typename C>
+ auto buffer_sequence_end(
+ const C & c);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:buffer_size buffer_size]
+
+[indexterm1 asio.indexterm.buffer_size..buffer_size]
+Get the total number of bytes in a buffer sequence.
+
+
+ template<
+ typename BufferSequence>
+ std::size_t buffer_size(
+ const BufferSequence & b);
+
+
+The `buffer_size` function determines the total size of all buffers in the buffer sequence, as if computed as follows:
+
+
+
+ size_t total_size = 0;
+ auto i = asio::buffer_sequence_begin(buffers);
+ auto end = asio::buffer_sequence_end(buffers);
+ for (; i != end; ++i)
+ {
+ const_buffer b(*i);
+ total_size += b.size();
+ }
+ return total_size;
+
+
+
+
+The `BufferSequence` template parameter may meet either of the `ConstBufferSequence` or `MutableBufferSequence` type requirements.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:buffered_read_stream buffered_read_stream]
+
+
+Adds buffering to the read-related operations of a stream.
+
+
+ template<
+ typename Stream>
+ class buffered_read_stream :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.buffered_read_stream.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_read_stream.lowest_layer_type [*lowest_layer_type]]]
+ [The type of the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_read_stream.next_layer_type [*next_layer_type]]]
+ [The type of the next layer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffered_read_stream.async_fill [*async_fill]]]
+ [Start an asynchronous fill. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.buffered_read_stream [*buffered_read_stream]]]
+ [Construct, passing the specified argument to initialise the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.close [*close]]]
+ [Close the stream. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.fill [*fill]]]
+ [Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+ Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.in_avail [*in_avail]]]
+ [Determine the amount of data that may be read without blocking. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.next_layer [*next_layer]]]
+ [Get a reference to the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.peek [*peek]]]
+ [Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.read_some [*read_some]]]
+ [Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Read some data from the stream. Returns the number of bytes read or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_read_stream.write_some [*write_some]]]
+ [Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+ Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffered_read_stream.default_buffer_size [*default_buffer_size]]]
+ [The default buffer size. ]
+ ]
+
+]
+
+The [link asio.reference.buffered_read_stream `buffered_read_stream`] class template can be used to add buffering to the synchronous and asynchronous read operations of a stream.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_read_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_fill buffered_read_stream::async_fill]
+
+[indexterm2 asio.indexterm.buffered_read_stream.async_fill..async_fill..buffered_read_stream]
+Start an asynchronous fill.
+
+
+ template<
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_fill(
+ ReadHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_read_some buffered_read_stream::async_read_some]
+
+[indexterm2 asio.indexterm.buffered_read_stream.async_read_some..async_read_some..buffered_read_stream]
+Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_write_some buffered_read_stream::async_write_some]
+
+[indexterm2 asio.indexterm.buffered_read_stream.async_write_some..async_write_some..buffered_read_stream]
+Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+
+[endsect]
+
+
+[section:buffered_read_stream buffered_read_stream::buffered_read_stream]
+
+[indexterm2 asio.indexterm.buffered_read_stream.buffered_read_stream..buffered_read_stream..buffered_read_stream]
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ explicit ``[link asio.reference.buffered_read_stream.buffered_read_stream.overload1 buffered_read_stream]``(
+ Arg & a);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.buffered_read_stream.overload1 more...]]``
+
+ template<
+ typename Arg>
+ ``[link asio.reference.buffered_read_stream.buffered_read_stream.overload2 buffered_read_stream]``(
+ Arg & a,
+ std::size_t buffer_size);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.buffered_read_stream.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::buffered_read_stream (1 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_read_stream(
+ Arg & a);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::buffered_read_stream (2 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_read_stream(
+ Arg & a,
+ std::size_t buffer_size);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close buffered_read_stream::close]
+
+[indexterm2 asio.indexterm.buffered_read_stream.close..close..buffered_read_stream]
+Close the stream.
+
+
+ void ``[link asio.reference.buffered_read_stream.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.close.overload1 more...]]``
+
+ void ``[link asio.reference.buffered_read_stream.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.close.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::close (1 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::close (2 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:default_buffer_size buffered_read_stream::default_buffer_size]
+
+[indexterm2 asio.indexterm.buffered_read_stream.default_buffer_size..default_buffer_size..buffered_read_stream]
+The default buffer size.
+
+
+ static const std::size_t default_buffer_size = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:executor_type buffered_read_stream::executor_type]
+
+[indexterm2 asio.indexterm.buffered_read_stream.executor_type..executor_type..buffered_read_stream]
+The type of the executor associated with the object.
+
+
+ typedef lowest_layer_type::executor_type executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_read_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:fill buffered_read_stream::fill]
+
+[indexterm2 asio.indexterm.buffered_read_stream.fill..fill..buffered_read_stream]
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+
+ std::size_t ``[link asio.reference.buffered_read_stream.fill.overload1 fill]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.fill.overload1 more...]]``
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred.
+
+
+ std::size_t ``[link asio.reference.buffered_read_stream.fill.overload2 fill]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.fill.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::fill (1 of 2 overloads)]
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+
+ std::size_t fill();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::fill (2 of 2 overloads)]
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred.
+
+
+ std::size_t fill(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor buffered_read_stream::get_executor]
+
+[indexterm2 asio.indexterm.buffered_read_stream.get_executor..get_executor..buffered_read_stream]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context buffered_read_stream::get_io_context]
+
+[indexterm2 asio.indexterm.buffered_read_stream.get_io_context..get_io_context..buffered_read_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service buffered_read_stream::get_io_service]
+
+[indexterm2 asio.indexterm.buffered_read_stream.get_io_service..get_io_service..buffered_read_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+[section:in_avail buffered_read_stream::in_avail]
+
+[indexterm2 asio.indexterm.buffered_read_stream.in_avail..in_avail..buffered_read_stream]
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t ``[link asio.reference.buffered_read_stream.in_avail.overload1 in_avail]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.in_avail.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.buffered_read_stream.in_avail.overload2 in_avail]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.in_avail.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::in_avail (1 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::in_avail (2 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer buffered_read_stream::lowest_layer]
+
+[indexterm2 asio.indexterm.buffered_read_stream.lowest_layer..lowest_layer..buffered_read_stream]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.buffered_read_stream.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.buffered_read_stream.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type buffered_read_stream::lowest_layer_type]
+
+[indexterm2 asio.indexterm.buffered_read_stream.lowest_layer_type..lowest_layer_type..buffered_read_stream]
+The type of the lowest layer.
+
+
+ typedef next_layer_type::lowest_layer_type lowest_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_read_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:next_layer buffered_read_stream::next_layer]
+
+[indexterm2 asio.indexterm.buffered_read_stream.next_layer..next_layer..buffered_read_stream]
+Get a reference to the next layer.
+
+
+ next_layer_type & next_layer();
+
+
+
+[endsect]
+
+
+
+[section:next_layer_type buffered_read_stream::next_layer_type]
+
+[indexterm2 asio.indexterm.buffered_read_stream.next_layer_type..next_layer_type..buffered_read_stream]
+The type of the next layer.
+
+
+ typedef remove_reference< Stream >::type next_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_read_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:peek buffered_read_stream::peek]
+
+[indexterm2 asio.indexterm.buffered_read_stream.peek..peek..buffered_read_stream]
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.peek.overload1 peek]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.peek.overload1 more...]]``
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.peek.overload2 peek]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.peek.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::peek (1 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::peek (2 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_some buffered_read_stream::read_some]
+
+[indexterm2 asio.indexterm.buffered_read_stream.read_some..read_some..buffered_read_stream]
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.read_some.overload1 more...]]``
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.read_some.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::read_some (1 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::read_some (2 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some buffered_read_stream::write_some]
+
+[indexterm2 asio.indexterm.buffered_read_stream.write_some..write_some..buffered_read_stream]
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.write_some.overload1 more...]]``
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_read_stream.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_read_stream.write_some.overload2 more...]]``
+
+
+[section:overload1 buffered_read_stream::write_some (1 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_read_stream::write_some (2 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffered_stream buffered_stream]
+
+
+Adds buffering to the read- and write-related operations of a stream.
+
+
+ template<
+ typename Stream>
+ class buffered_stream :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.buffered_stream.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_stream.lowest_layer_type [*lowest_layer_type]]]
+ [The type of the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_stream.next_layer_type [*next_layer_type]]]
+ [The type of the next layer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffered_stream.async_fill [*async_fill]]]
+ [Start an asynchronous fill. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.async_flush [*async_flush]]]
+ [Start an asynchronous flush. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.buffered_stream [*buffered_stream]]]
+ [Construct, passing the specified argument to initialise the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.close [*close]]]
+ [Close the stream. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.fill [*fill]]]
+ [Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+ Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.flush [*flush]]]
+ [Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+ Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.in_avail [*in_avail]]]
+ [Determine the amount of data that may be read without blocking. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.next_layer [*next_layer]]]
+ [Get a reference to the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.peek [*peek]]]
+ [Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.read_some [*read_some]]]
+ [Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Read some data from the stream. Returns the number of bytes read or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_stream.write_some [*write_some]]]
+ [Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+ Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred. ]
+ ]
+
+]
+
+The [link asio.reference.buffered_stream `buffered_stream`] class template can be used to add buffering to the synchronous and asynchronous read and write operations of a stream.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_fill buffered_stream::async_fill]
+
+[indexterm2 asio.indexterm.buffered_stream.async_fill..async_fill..buffered_stream]
+Start an asynchronous fill.
+
+
+ template<
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_fill(
+ ReadHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_flush buffered_stream::async_flush]
+
+[indexterm2 asio.indexterm.buffered_stream.async_flush..async_flush..buffered_stream]
+Start an asynchronous flush.
+
+
+ template<
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_flush(
+ WriteHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_read_some buffered_stream::async_read_some]
+
+[indexterm2 asio.indexterm.buffered_stream.async_read_some..async_read_some..buffered_stream]
+Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_write_some buffered_stream::async_write_some]
+
+[indexterm2 asio.indexterm.buffered_stream.async_write_some..async_write_some..buffered_stream]
+Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+
+[endsect]
+
+
+[section:buffered_stream buffered_stream::buffered_stream]
+
+[indexterm2 asio.indexterm.buffered_stream.buffered_stream..buffered_stream..buffered_stream]
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ explicit ``[link asio.reference.buffered_stream.buffered_stream.overload1 buffered_stream]``(
+ Arg & a);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.buffered_stream.overload1 more...]]``
+
+ template<
+ typename Arg>
+ explicit ``[link asio.reference.buffered_stream.buffered_stream.overload2 buffered_stream]``(
+ Arg & a,
+ std::size_t read_buffer_size,
+ std::size_t write_buffer_size);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.buffered_stream.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::buffered_stream (1 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_stream(
+ Arg & a);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::buffered_stream (2 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_stream(
+ Arg & a,
+ std::size_t read_buffer_size,
+ std::size_t write_buffer_size);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close buffered_stream::close]
+
+[indexterm2 asio.indexterm.buffered_stream.close..close..buffered_stream]
+Close the stream.
+
+
+ void ``[link asio.reference.buffered_stream.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.close.overload1 more...]]``
+
+ void ``[link asio.reference.buffered_stream.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.close.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::close (1 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::close (2 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type buffered_stream::executor_type]
+
+[indexterm2 asio.indexterm.buffered_stream.executor_type..executor_type..buffered_stream]
+The type of the executor associated with the object.
+
+
+ typedef lowest_layer_type::executor_type executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:fill buffered_stream::fill]
+
+[indexterm2 asio.indexterm.buffered_stream.fill..fill..buffered_stream]
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+
+ std::size_t ``[link asio.reference.buffered_stream.fill.overload1 fill]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.fill.overload1 more...]]``
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred.
+
+
+ std::size_t ``[link asio.reference.buffered_stream.fill.overload2 fill]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.fill.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::fill (1 of 2 overloads)]
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation. Throws an exception on failure.
+
+
+ std::size_t fill();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::fill (2 of 2 overloads)]
+
+
+Fill the buffer with some data. Returns the number of bytes placed in the buffer as a result of the operation, or 0 if an error occurred.
+
+
+ std::size_t fill(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:flush buffered_stream::flush]
+
+[indexterm2 asio.indexterm.buffered_stream.flush..flush..buffered_stream]
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+
+ std::size_t ``[link asio.reference.buffered_stream.flush.overload1 flush]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.flush.overload1 more...]]``
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred.
+
+
+ std::size_t ``[link asio.reference.buffered_stream.flush.overload2 flush]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.flush.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::flush (1 of 2 overloads)]
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+
+ std::size_t flush();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::flush (2 of 2 overloads)]
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred.
+
+
+ std::size_t flush(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor buffered_stream::get_executor]
+
+[indexterm2 asio.indexterm.buffered_stream.get_executor..get_executor..buffered_stream]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context buffered_stream::get_io_context]
+
+[indexterm2 asio.indexterm.buffered_stream.get_io_context..get_io_context..buffered_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service buffered_stream::get_io_service]
+
+[indexterm2 asio.indexterm.buffered_stream.get_io_service..get_io_service..buffered_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+[section:in_avail buffered_stream::in_avail]
+
+[indexterm2 asio.indexterm.buffered_stream.in_avail..in_avail..buffered_stream]
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t ``[link asio.reference.buffered_stream.in_avail.overload1 in_avail]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.in_avail.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.buffered_stream.in_avail.overload2 in_avail]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.in_avail.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::in_avail (1 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::in_avail (2 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer buffered_stream::lowest_layer]
+
+[indexterm2 asio.indexterm.buffered_stream.lowest_layer..lowest_layer..buffered_stream]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.buffered_stream.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.buffered_stream.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type buffered_stream::lowest_layer_type]
+
+[indexterm2 asio.indexterm.buffered_stream.lowest_layer_type..lowest_layer_type..buffered_stream]
+The type of the lowest layer.
+
+
+ typedef next_layer_type::lowest_layer_type lowest_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:next_layer buffered_stream::next_layer]
+
+[indexterm2 asio.indexterm.buffered_stream.next_layer..next_layer..buffered_stream]
+Get a reference to the next layer.
+
+
+ next_layer_type & next_layer();
+
+
+
+[endsect]
+
+
+
+[section:next_layer_type buffered_stream::next_layer_type]
+
+[indexterm2 asio.indexterm.buffered_stream.next_layer_type..next_layer_type..buffered_stream]
+The type of the next layer.
+
+
+ typedef remove_reference< Stream >::type next_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:peek buffered_stream::peek]
+
+[indexterm2 asio.indexterm.buffered_stream.peek..peek..buffered_stream]
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.peek.overload1 peek]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.peek.overload1 more...]]``
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.peek.overload2 peek]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.peek.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::peek (1 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::peek (2 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_some buffered_stream::read_some]
+
+[indexterm2 asio.indexterm.buffered_stream.read_some..read_some..buffered_stream]
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.read_some.overload1 more...]]``
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.read_some.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::read_some (1 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::read_some (2 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some buffered_stream::write_some]
+
+[indexterm2 asio.indexterm.buffered_stream.write_some..write_some..buffered_stream]
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.write_some.overload1 more...]]``
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_stream.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_stream.write_some.overload2 more...]]``
+
+
+[section:overload1 buffered_stream::write_some (1 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_stream::write_some (2 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:buffered_write_stream buffered_write_stream]
+
+
+Adds buffering to the write-related operations of a stream.
+
+
+ template<
+ typename Stream>
+ class buffered_write_stream :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.buffered_write_stream.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_write_stream.lowest_layer_type [*lowest_layer_type]]]
+ [The type of the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffered_write_stream.next_layer_type [*next_layer_type]]]
+ [The type of the next layer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffered_write_stream.async_flush [*async_flush]]]
+ [Start an asynchronous flush. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.buffered_write_stream [*buffered_write_stream]]]
+ [Construct, passing the specified argument to initialise the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.close [*close]]]
+ [Close the stream. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.flush [*flush]]]
+ [Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+ Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.in_avail [*in_avail]]]
+ [Determine the amount of data that may be read without blocking. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.next_layer [*next_layer]]]
+ [Get a reference to the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.peek [*peek]]]
+ [Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.read_some [*read_some]]]
+ [Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+ Read some data from the stream. Returns the number of bytes read or 0 if an error occurred. ]
+ ]
+
+ [
+ [[link asio.reference.buffered_write_stream.write_some [*write_some]]]
+ [Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+ Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred and the error handler did not throw. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffered_write_stream.default_buffer_size [*default_buffer_size]]]
+ [The default buffer size. ]
+ ]
+
+]
+
+The [link asio.reference.buffered_write_stream `buffered_write_stream`] class template can be used to add buffering to the synchronous and asynchronous write operations of a stream.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_write_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:async_flush buffered_write_stream::async_flush]
+
+[indexterm2 asio.indexterm.buffered_write_stream.async_flush..async_flush..buffered_write_stream]
+Start an asynchronous flush.
+
+
+ template<
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_flush(
+ WriteHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_read_some buffered_write_stream::async_read_some]
+
+[indexterm2 asio.indexterm.buffered_write_stream.async_read_some..async_read_some..buffered_write_stream]
+Start an asynchronous read. The buffer into which the data will be read must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+
+[endsect]
+
+
+
+[section:async_write_some buffered_write_stream::async_write_some]
+
+[indexterm2 asio.indexterm.buffered_write_stream.async_write_some..async_write_some..buffered_write_stream]
+Start an asynchronous write. The data being written must be valid for the lifetime of the asynchronous operation.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+
+[endsect]
+
+
+[section:buffered_write_stream buffered_write_stream::buffered_write_stream]
+
+[indexterm2 asio.indexterm.buffered_write_stream.buffered_write_stream..buffered_write_stream..buffered_write_stream]
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ explicit ``[link asio.reference.buffered_write_stream.buffered_write_stream.overload1 buffered_write_stream]``(
+ Arg & a);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.buffered_write_stream.overload1 more...]]``
+
+ template<
+ typename Arg>
+ ``[link asio.reference.buffered_write_stream.buffered_write_stream.overload2 buffered_write_stream]``(
+ Arg & a,
+ std::size_t buffer_size);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.buffered_write_stream.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::buffered_write_stream (1 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_write_stream(
+ Arg & a);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::buffered_write_stream (2 of 2 overloads)]
+
+
+Construct, passing the specified argument to initialise the next layer.
+
+
+ template<
+ typename Arg>
+ buffered_write_stream(
+ Arg & a,
+ std::size_t buffer_size);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close buffered_write_stream::close]
+
+[indexterm2 asio.indexterm.buffered_write_stream.close..close..buffered_write_stream]
+Close the stream.
+
+
+ void ``[link asio.reference.buffered_write_stream.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.close.overload1 more...]]``
+
+ void ``[link asio.reference.buffered_write_stream.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.close.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::close (1 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::close (2 of 2 overloads)]
+
+
+Close the stream.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:default_buffer_size buffered_write_stream::default_buffer_size]
+
+[indexterm2 asio.indexterm.buffered_write_stream.default_buffer_size..default_buffer_size..buffered_write_stream]
+The default buffer size.
+
+
+ static const std::size_t default_buffer_size = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:executor_type buffered_write_stream::executor_type]
+
+[indexterm2 asio.indexterm.buffered_write_stream.executor_type..executor_type..buffered_write_stream]
+The type of the executor associated with the object.
+
+
+ typedef lowest_layer_type::executor_type executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_write_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:flush buffered_write_stream::flush]
+
+[indexterm2 asio.indexterm.buffered_write_stream.flush..flush..buffered_write_stream]
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+
+ std::size_t ``[link asio.reference.buffered_write_stream.flush.overload1 flush]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.flush.overload1 more...]]``
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred.
+
+
+ std::size_t ``[link asio.reference.buffered_write_stream.flush.overload2 flush]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.flush.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::flush (1 of 2 overloads)]
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation. Throws an exception on failure.
+
+
+ std::size_t flush();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::flush (2 of 2 overloads)]
+
+
+Flush all data from the buffer to the next layer. Returns the number of bytes written to the next layer on the last write operation, or 0 if an error occurred.
+
+
+ std::size_t flush(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor buffered_write_stream::get_executor]
+
+[indexterm2 asio.indexterm.buffered_write_stream.get_executor..get_executor..buffered_write_stream]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context buffered_write_stream::get_io_context]
+
+[indexterm2 asio.indexterm.buffered_write_stream.get_io_context..get_io_context..buffered_write_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service buffered_write_stream::get_io_service]
+
+[indexterm2 asio.indexterm.buffered_write_stream.get_io_service..get_io_service..buffered_write_stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+[section:in_avail buffered_write_stream::in_avail]
+
+[indexterm2 asio.indexterm.buffered_write_stream.in_avail..in_avail..buffered_write_stream]
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t ``[link asio.reference.buffered_write_stream.in_avail.overload1 in_avail]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.in_avail.overload1 more...]]``
+
+ std::size_t ``[link asio.reference.buffered_write_stream.in_avail.overload2 in_avail]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.in_avail.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::in_avail (1 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::in_avail (2 of 2 overloads)]
+
+
+Determine the amount of data that may be read without blocking.
+
+
+ std::size_t in_avail(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:lowest_layer buffered_write_stream::lowest_layer]
+
+[indexterm2 asio.indexterm.buffered_write_stream.lowest_layer..lowest_layer..buffered_write_stream]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.buffered_write_stream.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.buffered_write_stream.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type buffered_write_stream::lowest_layer_type]
+
+[indexterm2 asio.indexterm.buffered_write_stream.lowest_layer_type..lowest_layer_type..buffered_write_stream]
+The type of the lowest layer.
+
+
+ typedef next_layer_type::lowest_layer_type lowest_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_write_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:next_layer buffered_write_stream::next_layer]
+
+[indexterm2 asio.indexterm.buffered_write_stream.next_layer..next_layer..buffered_write_stream]
+Get a reference to the next layer.
+
+
+ next_layer_type & next_layer();
+
+
+
+[endsect]
+
+
+
+[section:next_layer_type buffered_write_stream::next_layer_type]
+
+[indexterm2 asio.indexterm.buffered_write_stream.next_layer_type..next_layer_type..buffered_write_stream]
+The type of the next layer.
+
+
+ typedef remove_reference< Stream >::type next_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffered_write_stream.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:peek buffered_write_stream::peek]
+
+[indexterm2 asio.indexterm.buffered_write_stream.peek..peek..buffered_write_stream]
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.peek.overload1 peek]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.peek.overload1 more...]]``
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.peek.overload2 peek]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.peek.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::peek (1 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::peek (2 of 2 overloads)]
+
+
+Peek at the incoming data on the stream. Returns the number of bytes read, or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t peek(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_some buffered_write_stream::read_some]
+
+[indexterm2 asio.indexterm.buffered_write_stream.read_some..read_some..buffered_write_stream]
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.read_some.overload1 more...]]``
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.read_some.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::read_some (1 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::read_some (2 of 2 overloads)]
+
+
+Read some data from the stream. Returns the number of bytes read or 0 if an error occurred.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some buffered_write_stream::write_some]
+
+[indexterm2 asio.indexterm.buffered_write_stream.write_some..write_some..buffered_write_stream]
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.write_some.overload1 more...]]``
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred and the error handler did not throw.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.buffered_write_stream.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.buffered_write_stream.write_some.overload2 more...]]``
+
+
+[section:overload1 buffered_write_stream::write_some (1 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written. Throws an exception on failure.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffered_write_stream::write_some (2 of 2 overloads)]
+
+
+Write the given data to the stream. Returns the number of bytes written, or 0 if an error occurred and the error handler did not throw.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:buffers_begin buffers_begin]
+
+[indexterm1 asio.indexterm.buffers_begin..buffers_begin]
+Construct an iterator representing the beginning of the buffers' data.
+
+
+ template<
+ typename BufferSequence>
+ buffers_iterator< BufferSequence > buffers_begin(
+ const BufferSequence & buffers);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:buffers_end buffers_end]
+
+[indexterm1 asio.indexterm.buffers_end..buffers_end]
+Construct an iterator representing the end of the buffers' data.
+
+
+ template<
+ typename BufferSequence>
+ buffers_iterator< BufferSequence > buffers_end(
+ const BufferSequence & buffers);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:buffers_iterator buffers_iterator]
+
+
+A random access iterator over the bytes in a buffer sequence.
+
+
+ template<
+ typename BufferSequence,
+ typename ByteType = char>
+ class buffers_iterator
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.buffers_iterator.difference_type [*difference_type]]]
+ [The type used for the distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffers_iterator.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffers_iterator.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffers_iterator.reference [*reference]]]
+ [The type of the result of applying operator*() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.buffers_iterator.value_type [*value_type]]]
+ [The type of the value pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffers_iterator.begin [*begin]]]
+ [Construct an iterator representing the beginning of the buffers' data. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.buffers_iterator [*buffers_iterator]]]
+ [Default constructor. Creates an iterator in an undefined state. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.end [*end]]]
+ [Construct an iterator representing the end of the buffers' data. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_plus__eq_ [*operator+=]]]
+ [Addition operator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_minus__minus_ [*operator--]]]
+ [Decrement operator (prefix).
+
+ Decrement operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_minus__eq_ [*operator-=]]]
+ [Subtraction operator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_lb__rb_ [*operator\[\]]]]
+ [Access an individual element. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_plus_ [*operator+]]]
+ [Addition operator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_minus_ [*operator-]]]
+ [Subtraction operator. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_lt_ [*operator<]]]
+ [Compare two iterators. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_lt__eq_ [*operator<=]]]
+ [Compare two iterators. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_gt_ [*operator>]]]
+ [Compare two iterators. ]
+ ]
+
+ [
+ [[link asio.reference.buffers_iterator.operator_gt__eq_ [*operator>=]]]
+ [Compare two iterators. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:begin buffers_iterator::begin]
+
+[indexterm2 asio.indexterm.buffers_iterator.begin..begin..buffers_iterator]
+Construct an iterator representing the beginning of the buffers' data.
+
+
+ static buffers_iterator begin(
+ const BufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:buffers_iterator buffers_iterator::buffers_iterator]
+
+[indexterm2 asio.indexterm.buffers_iterator.buffers_iterator..buffers_iterator..buffers_iterator]
+Default constructor. Creates an iterator in an undefined state.
+
+
+ buffers_iterator();
+
+
+
+[endsect]
+
+
+
+[section:difference_type buffers_iterator::difference_type]
+
+[indexterm2 asio.indexterm.buffers_iterator.difference_type..difference_type..buffers_iterator]
+The type used for the distance between two iterators.
+
+
+ typedef std::ptrdiff_t difference_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:end buffers_iterator::end]
+
+[indexterm2 asio.indexterm.buffers_iterator.end..end..buffers_iterator]
+Construct an iterator representing the end of the buffers' data.
+
+
+ static buffers_iterator end(
+ const BufferSequence & buffers);
+
+
+
+[endsect]
+
+
+
+[section:iterator_category buffers_iterator::iterator_category]
+
+[indexterm2 asio.indexterm.buffers_iterator.iterator_category..iterator_category..buffers_iterator]
+The iterator category.
+
+
+ typedef std::random_access_iterator_tag iterator_category;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator__star_ buffers_iterator::operator *]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator__star_..operator *..buffers_iterator]
+Dereference an iterator.
+
+
+ reference operator *() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ buffers_iterator::operator!=]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_not__eq_..operator!=..buffers_iterator]
+Test two iterators for inequality.
+
+
+ friend bool operator!=(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_plus_ buffers_iterator::operator+]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_plus_..operator+..buffers_iterator]
+Addition operator.
+
+
+ friend buffers_iterator ``[link asio.reference.buffers_iterator.operator_plus_.overload1 operator+]``(
+ const buffers_iterator & iter,
+ std::ptrdiff_t difference);
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_plus_.overload1 more...]]``
+
+ friend buffers_iterator ``[link asio.reference.buffers_iterator.operator_plus_.overload2 operator+]``(
+ std::ptrdiff_t difference,
+ const buffers_iterator & iter);
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_plus_.overload2 more...]]``
+
+
+[section:overload1 buffers_iterator::operator+ (1 of 2 overloads)]
+
+
+Addition operator.
+
+
+ friend buffers_iterator operator+(
+ const buffers_iterator & iter,
+ std::ptrdiff_t difference);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 buffers_iterator::operator+ (2 of 2 overloads)]
+
+
+Addition operator.
+
+
+ friend buffers_iterator operator+(
+ std::ptrdiff_t difference,
+ const buffers_iterator & iter);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_plus__plus_ buffers_iterator::operator++]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_plus__plus_..operator++..buffers_iterator]
+Increment operator (prefix).
+
+
+ buffers_iterator & ``[link asio.reference.buffers_iterator.operator_plus__plus_.overload1 operator++]``();
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_plus__plus_.overload1 more...]]``
+
+
+Increment operator (postfix).
+
+
+ buffers_iterator ``[link asio.reference.buffers_iterator.operator_plus__plus_.overload2 operator++]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_plus__plus_.overload2 more...]]``
+
+
+[section:overload1 buffers_iterator::operator++ (1 of 2 overloads)]
+
+
+Increment operator (prefix).
+
+
+ buffers_iterator & operator++();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffers_iterator::operator++ (2 of 2 overloads)]
+
+
+Increment operator (postfix).
+
+
+ buffers_iterator operator++(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_plus__eq_ buffers_iterator::operator+=]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_plus__eq_..operator+=..buffers_iterator]
+Addition operator.
+
+
+ buffers_iterator & operator+=(
+ std::ptrdiff_t difference);
+
+
+
+[endsect]
+
+
+[section:operator_minus_ buffers_iterator::operator-]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_minus_..operator-..buffers_iterator]
+Subtraction operator.
+
+
+ friend buffers_iterator ``[link asio.reference.buffers_iterator.operator_minus_.overload1 operator-]``(
+ const buffers_iterator & iter,
+ std::ptrdiff_t difference);
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_minus_.overload1 more...]]``
+
+ friend std::ptrdiff_t ``[link asio.reference.buffers_iterator.operator_minus_.overload2 operator-]``(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_minus_.overload2 more...]]``
+
+
+[section:overload1 buffers_iterator::operator- (1 of 2 overloads)]
+
+
+Subtraction operator.
+
+
+ friend buffers_iterator operator-(
+ const buffers_iterator & iter,
+ std::ptrdiff_t difference);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 buffers_iterator::operator- (2 of 2 overloads)]
+
+
+Subtraction operator.
+
+
+ friend std::ptrdiff_t operator-(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_minus__minus_ buffers_iterator::operator--]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_minus__minus_..operator--..buffers_iterator]
+Decrement operator (prefix).
+
+
+ buffers_iterator & ``[link asio.reference.buffers_iterator.operator_minus__minus_.overload1 operator--]``();
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_minus__minus_.overload1 more...]]``
+
+
+Decrement operator (postfix).
+
+
+ buffers_iterator ``[link asio.reference.buffers_iterator.operator_minus__minus_.overload2 operator--]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.buffers_iterator.operator_minus__minus_.overload2 more...]]``
+
+
+[section:overload1 buffers_iterator::operator-- (1 of 2 overloads)]
+
+
+Decrement operator (prefix).
+
+
+ buffers_iterator & operator--();
+
+
+
+[endsect]
+
+
+
+[section:overload2 buffers_iterator::operator-- (2 of 2 overloads)]
+
+
+Decrement operator (postfix).
+
+
+ buffers_iterator operator--(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_minus__eq_ buffers_iterator::operator-=]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_minus__eq_..operator-=..buffers_iterator]
+Subtraction operator.
+
+
+ buffers_iterator & operator-=(
+ std::ptrdiff_t difference);
+
+
+
+[endsect]
+
+
+
+[section:operator_arrow_ buffers_iterator::operator->]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_arrow_..operator->..buffers_iterator]
+Dereference an iterator.
+
+
+ pointer operator->() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_lt_ buffers_iterator::operator<]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_lt_..operator<..buffers_iterator]
+Compare two iterators.
+
+
+ friend bool operator<(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt__eq_ buffers_iterator::operator<=]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_lt__eq_..operator<=..buffers_iterator]
+Compare two iterators.
+
+
+ friend bool operator<=(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ buffers_iterator::operator==]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_eq__eq_..operator==..buffers_iterator]
+Test two iterators for equality.
+
+
+ friend bool operator==(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ buffers_iterator::operator>]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_gt_..operator>..buffers_iterator]
+Compare two iterators.
+
+
+ friend bool operator>(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ buffers_iterator::operator>=]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_gt__eq_..operator>=..buffers_iterator]
+Compare two iterators.
+
+
+ friend bool operator>=(
+ const buffers_iterator & a,
+ const buffers_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lb__rb_ buffers_iterator::operator\[\]]
+
+[indexterm2 asio.indexterm.buffers_iterator.operator_lb__rb_..operator\[\]..buffers_iterator]
+Access an individual element.
+
+
+ reference operator[](
+ std::ptrdiff_t difference) const;
+
+
+
+[endsect]
+
+
+
+[section:pointer buffers_iterator::pointer]
+
+[indexterm2 asio.indexterm.buffers_iterator.pointer..pointer..buffers_iterator]
+The type of the result of applying `operator->()` to the iterator.
+
+
+ typedef const_or_non_const_ByteType * pointer;
+
+
+
+If the buffer sequence stores buffer objects that are convertible to [link asio.reference.mutable_buffer `mutable_buffer`], this is a pointer to a non-const ByteType. Otherwise, a pointer to a const ByteType.
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reference buffers_iterator::reference]
+
+[indexterm2 asio.indexterm.buffers_iterator.reference..reference..buffers_iterator]
+The type of the result of applying `operator*()` to the iterator.
+
+
+ typedef const_or_non_const_ByteType & reference;
+
+
+
+If the buffer sequence stores buffer objects that are convertible to [link asio.reference.mutable_buffer `mutable_buffer`], this is a reference to a non-const ByteType. Otherwise, a reference to a const ByteType.
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:value_type buffers_iterator::value_type]
+
+[indexterm2 asio.indexterm.buffers_iterator.value_type..value_type..buffers_iterator]
+The type of the value pointed to by the iterator.
+
+
+ typedef ByteType value_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffers_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:connect connect]
+
+[indexterm1 asio.indexterm.connect..connect]
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``>
+ Protocol::endpoint ``[link asio.reference.connect.overload1 connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``>
+ Protocol::endpoint ``[link asio.reference.connect.overload2 connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ asio::error_code & ec,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator ``[link asio.reference.connect.overload3 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator ``[link asio.reference.connect.overload4 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ asio::error_code & ec,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator ``[link asio.reference.connect.overload5 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end);
+ `` [''''&raquo;''' [link asio.reference.connect.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator ``[link asio.reference.connect.overload6 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.connect.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Protocol::endpoint ``[link asio.reference.connect.overload7 connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Protocol::endpoint ``[link asio.reference.connect.overload8 connect]``(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ asio::error_code & ec,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload8 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator ``[link asio.reference.connect.overload9 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload9 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator ``[link asio.reference.connect.overload10 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ asio::error_code & ec,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.connect.overload10 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator ``[link asio.reference.connect.overload11 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition);
+ `` [''''&raquo;''' [link asio.reference.connect.overload11 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator ``[link asio.reference.connect.overload12 connect]``(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.connect.overload12 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/connect.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 connect (1 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``>
+ Protocol::endpoint connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+]
+
+
+[heading Return Value]
+
+The successfully connected endpoint.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Example]
+
+
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+ asio::connect(s, r.resolve(q));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 connect (2 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``>
+ Protocol::endpoint connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ asio::error_code & ec,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, the successfully connected endpoint. Otherwise, a default-constructed endpoint.
+
+
+[heading Example]
+
+
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+ asio::error_code ec;
+ asio::connect(s, r.resolve(q), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 connect (3 of 12 overloads)]
+
+
+(Deprecated.) Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 connect (4 of 12 overloads)]
+
+
+(Deprecated.) Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ asio::error_code & ec,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 connect (5 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+]
+
+
+[heading Return Value]
+
+An iterator denoting the successfully connected endpoint.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Example]
+
+
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::resolver::results_type e = r.resolve(q);
+ tcp::socket s(io_context);
+ asio::connect(s, e.begin(), e.end());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 connect (6 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ asio::error_code & ec);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Example]
+
+
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::resolver::results_type e = r.resolve(q);
+ tcp::socket s(io_context);
+ asio::error_code ec;
+ asio::connect(s, e.begin(), e.end(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 connect (7 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Protocol::endpoint connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+]
+
+
+[heading Return Value]
+
+The successfully connected endpoint.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+ tcp::endpoint e = asio::connect(s,
+ r.resolve(q), my_connect_condition());
+ std::cout << "Connected to: " << e << std::endl;
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 connect (8 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename ``[link asio.reference.EndpointSequence EndpointSequence]``,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Protocol::endpoint connect(
+ basic_socket< Protocol > & s,
+ const EndpointSequence & endpoints,
+ ConnectCondition connect_condition,
+ asio::error_code & ec,
+ typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[endpoints][A sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, the successfully connected endpoint. Otherwise, a default-constructed endpoint.
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::socket s(io_context);
+ asio::error_code ec;
+ tcp::endpoint e = asio::connect(s,
+ r.resolve(q), my_connect_condition(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ std::cout << "Connected to: " << e << std::endl;
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 connect (9 of 12 overloads)]
+
+
+(Deprecated.) Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 connect (10 of 12 overloads)]
+
+
+(Deprecated.) Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ ConnectCondition connect_condition,
+ asio::error_code & ec,
+ typename enable_if<!is_endpoint_sequence< Iterator >::value >::type * = 0);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Remarks]
+
+This overload assumes that a default constructed object of type `Iterator` represents the end of the sequence. This is a valid assumption for iterator types such as `asio::ip::tcp::resolver::iterator`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 connect (11 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+]
+
+
+[heading Return Value]
+
+An iterator denoting the successfully connected endpoint.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the sequence is empty, the associated `error_code` is `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::resolver::results_type e = r.resolve(q);
+ tcp::socket s(io_context);
+ tcp::resolver::results_type::iterator i = asio::connect(
+ s, e.begin(), e.end(), my_connect_condition());
+ std::cout << "Connected to: " << i->endpoint() << std::endl;
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 connect (12 of 12 overloads)]
+
+
+Establishes a socket connection by trying each endpoint in a sequence.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``,
+ typename Iterator,
+ typename ``[link asio.reference.ConnectCondition ConnectCondition]``>
+ Iterator connect(
+ basic_socket< Protocol > & s,
+ Iterator begin,
+ Iterator end,
+ ConnectCondition connect_condition,
+ asio::error_code & ec);
+
+
+This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's `connect` member function, once for each endpoint in the sequence, until a connection is successfully established.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The socket to be connected. If the socket is already open, it will be closed.]]
+
+[[begin][An iterator pointing to the start of a sequence of endpoints.]]
+
+[[end][An iterator pointing to the end of a sequence of endpoints.]]
+
+[[connect_condition][A function object that is called prior to each connection attempt. The signature of the function object must be:
+``
+ bool connect_condition(
+ const asio::error_code& ec,
+ const typename Protocol::endpoint& next);
+``
+The `ec` parameter contains the result from the most recent connect operation. Before the first connection attempt, `ec` is always set to indicate success. The `next` parameter is the next endpoint to be tried. The function object should return true if the next endpoint should be tried, and false if it should be skipped.]]
+
+[[ec][Set to indicate what error occurred, if any. If the sequence is empty, set to `asio::error::not_found`. Otherwise, contains the error from the last connection attempt.]]
+
+]
+
+
+[heading Return Value]
+
+On success, an iterator denoting the successfully connected endpoint. Otherwise, the end iterator.
+
+
+[heading Example]
+
+The following connect condition function object can be used to output information about the individual connection attempts:
+
+ struct my_connect_condition
+ {
+ bool operator()(
+ const asio::error_code& ec,
+ const::tcp::endpoint& next)
+ {
+ if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ std::cout << "Trying: " << next << std::endl;
+ return true;
+ }
+ };
+
+
+It would be used with the `asio::connect` function as follows:
+
+ tcp::resolver r(io_context);
+ tcp::resolver::query q("host", "service");
+ tcp::resolver::results_type e = r.resolve(q);
+ tcp::socket s(io_context);
+ asio::error_code ec;
+ tcp::resolver::results_type::iterator i = asio::connect(
+ s, e.begin(), e.end(), my_connect_condition());
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ std::cout << "Connected to: " << i->endpoint() << std::endl;
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:const_buffer const_buffer]
+
+
+Holds a buffer that cannot be modified.
+
+
+ class const_buffer
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.const_buffer [*const_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range.
+
+ Construct a non-modifiable buffer from a modifiable one. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus_ [*operator+]]]
+ [Create a new non-modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.const_buffer `const_buffer`] class provides a safe representation of a buffer that cannot be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::const_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:const_buffer const_buffer::const_buffer]
+
+[indexterm2 asio.indexterm.const_buffer.const_buffer..const_buffer..const_buffer]
+Construct an empty buffer.
+
+
+ ``[link asio.reference.const_buffer.const_buffer.overload1 const_buffer]``();
+ `` [''''&raquo;''' [link asio.reference.const_buffer.const_buffer.overload1 more...]]``
+
+
+Construct a buffer to represent a given memory range.
+
+
+ ``[link asio.reference.const_buffer.const_buffer.overload2 const_buffer]``(
+ const void * data,
+ std::size_t size);
+ `` [''''&raquo;''' [link asio.reference.const_buffer.const_buffer.overload2 more...]]``
+
+
+Construct a non-modifiable buffer from a modifiable one.
+
+
+ ``[link asio.reference.const_buffer.const_buffer.overload3 const_buffer]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.const_buffer.const_buffer.overload3 more...]]``
+
+
+[section:overload1 const_buffer::const_buffer (1 of 3 overloads)]
+
+
+Construct an empty buffer.
+
+
+ const_buffer();
+
+
+
+[endsect]
+
+
+
+[section:overload2 const_buffer::const_buffer (2 of 3 overloads)]
+
+
+Construct a buffer to represent a given memory range.
+
+
+ const_buffer(
+ const void * data,
+ std::size_t size);
+
+
+
+[endsect]
+
+
+
+[section:overload3 const_buffer::const_buffer (3 of 3 overloads)]
+
+
+Construct a non-modifiable buffer from a modifiable one.
+
+
+ const_buffer(
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:data const_buffer::data]
+
+[indexterm2 asio.indexterm.const_buffer.data..data..const_buffer]
+Get a pointer to the beginning of the memory range.
+
+
+ const void * data() const;
+
+
+
+[endsect]
+
+
+[section:operator_plus_ const_buffer::operator+]
+
+[indexterm2 asio.indexterm.const_buffer.operator_plus_..operator+..const_buffer]
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer ``[link asio.reference.const_buffer.operator_plus_.overload1 operator+]``(
+ const const_buffer & b,
+ std::size_t n);
+ `` [''''&raquo;''' [link asio.reference.const_buffer.operator_plus_.overload1 more...]]``
+
+ const_buffer ``[link asio.reference.const_buffer.operator_plus_.overload2 operator+]``(
+ std::size_t n,
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.const_buffer.operator_plus_.overload2 more...]]``
+
+
+[section:overload1 const_buffer::operator+ (1 of 2 overloads)]
+
+
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer operator+(
+ const const_buffer & b,
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:overload2 const_buffer::operator+ (2 of 2 overloads)]
+
+
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer operator+(
+ std::size_t n,
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_plus__eq_ const_buffer::operator+=]
+
+[indexterm2 asio.indexterm.const_buffer.operator_plus__eq_..operator+=..const_buffer]
+Move the start of the buffer by the specified number of bytes.
+
+
+ const_buffer & operator+=(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size const_buffer::size]
+
+[indexterm2 asio.indexterm.const_buffer.size..size..const_buffer]
+Get the size of the memory range.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:const_buffers_1 const_buffers_1]
+
+
+(Deprecated: Use [link asio.reference.const_buffer `const_buffer`].) Adapts a single non-modifiable buffer so that it meets the requirements of the ConstBufferSequence concept.
+
+
+ class const_buffers_1 :
+ public const_buffer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.const_buffers_1.const_iterator [*const_iterator]]]
+ [A random-access iterator type that may be used to read elements. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.const_buffers_1.value_type [*value_type]]]
+ [The type for each element in the list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffers_1.begin [*begin]]]
+ [Get a random-access iterator to the first element. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffers_1.const_buffers_1 [*const_buffers_1]]]
+ [Construct to represent a given memory range.
+
+ Construct to represent a single non-modifiable buffer. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffers_1.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffers_1.end [*end]]]
+ [Get a random-access iterator for one past the last element. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffers_1.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffers_1.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffers_1.operator_plus_ [*operator+]]]
+ [Create a new non-modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:begin const_buffers_1::begin]
+
+[indexterm2 asio.indexterm.const_buffers_1.begin..begin..const_buffers_1]
+Get a random-access iterator to the first element.
+
+
+ const_iterator begin() const;
+
+
+
+[endsect]
+
+
+[section:const_buffers_1 const_buffers_1::const_buffers_1]
+
+[indexterm2 asio.indexterm.const_buffers_1.const_buffers_1..const_buffers_1..const_buffers_1]
+Construct to represent a given memory range.
+
+
+ ``[link asio.reference.const_buffers_1.const_buffers_1.overload1 const_buffers_1]``(
+ const void * data,
+ std::size_t size);
+ `` [''''&raquo;''' [link asio.reference.const_buffers_1.const_buffers_1.overload1 more...]]``
+
+
+Construct to represent a single non-modifiable buffer.
+
+
+ explicit ``[link asio.reference.const_buffers_1.const_buffers_1.overload2 const_buffers_1]``(
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.const_buffers_1.const_buffers_1.overload2 more...]]``
+
+
+[section:overload1 const_buffers_1::const_buffers_1 (1 of 2 overloads)]
+
+
+Construct to represent a given memory range.
+
+
+ const_buffers_1(
+ const void * data,
+ std::size_t size);
+
+
+
+[endsect]
+
+
+
+[section:overload2 const_buffers_1::const_buffers_1 (2 of 2 overloads)]
+
+
+Construct to represent a single non-modifiable buffer.
+
+
+ const_buffers_1(
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:const_iterator const_buffers_1::const_iterator]
+
+[indexterm2 asio.indexterm.const_buffers_1.const_iterator..const_iterator..const_buffers_1]
+A random-access iterator type that may be used to read elements.
+
+
+ typedef const const_buffer * const_iterator;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:data const_buffers_1::data]
+
+
+['Inherited from const_buffer.]
+
+[indexterm2 asio.indexterm.const_buffers_1.data..data..const_buffers_1]
+Get a pointer to the beginning of the memory range.
+
+
+ const void * data() const;
+
+
+
+[endsect]
+
+
+
+[section:end const_buffers_1::end]
+
+[indexterm2 asio.indexterm.const_buffers_1.end..end..const_buffers_1]
+Get a random-access iterator for one past the last element.
+
+
+ const_iterator end() const;
+
+
+
+[endsect]
+
+
+[section:operator_plus_ const_buffers_1::operator+]
+
+[indexterm2 asio.indexterm.const_buffers_1.operator_plus_..operator+..const_buffers_1]
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer ``[link asio.reference.const_buffers_1.operator_plus_.overload1 operator+]``(
+ const const_buffer & b,
+ std::size_t n);
+ `` [''''&raquo;''' [link asio.reference.const_buffers_1.operator_plus_.overload1 more...]]``
+
+ const_buffer ``[link asio.reference.const_buffers_1.operator_plus_.overload2 operator+]``(
+ std::size_t n,
+ const const_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.const_buffers_1.operator_plus_.overload2 more...]]``
+
+
+[section:overload1 const_buffers_1::operator+ (1 of 2 overloads)]
+
+
+['Inherited from const_buffer.]
+
+
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer operator+(
+ const const_buffer & b,
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:overload2 const_buffers_1::operator+ (2 of 2 overloads)]
+
+
+['Inherited from const_buffer.]
+
+
+Create a new non-modifiable buffer that is offset from the start of another.
+
+
+ const_buffer operator+(
+ std::size_t n,
+ const const_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_plus__eq_ const_buffers_1::operator+=]
+
+
+['Inherited from const_buffer.]
+
+[indexterm2 asio.indexterm.const_buffers_1.operator_plus__eq_..operator+=..const_buffers_1]
+Move the start of the buffer by the specified number of bytes.
+
+
+ const_buffer & operator+=(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size const_buffers_1::size]
+
+
+['Inherited from const_buffer.]
+
+[indexterm2 asio.indexterm.const_buffers_1.size..size..const_buffers_1]
+Get the size of the memory range.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[section:value_type const_buffers_1::value_type]
+
+[indexterm2 asio.indexterm.const_buffers_1.value_type..value_type..const_buffers_1]
+The type for each element in the list of buffers.
+
+
+ typedef const_buffer value_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.const_buffer [*const_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range.
+
+ Construct a non-modifiable buffer from a modifiable one. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus_ [*operator+]]]
+ [Create a new non-modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.const_buffer `const_buffer`] class provides a safe representation of a buffer that cannot be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::const_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:coroutine coroutine]
+
+
+Provides support for implementing stackless coroutines.
+
+
+ class coroutine
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.coroutine.coroutine [*coroutine]]]
+ [Constructs a coroutine in its initial state. ]
+ ]
+
+ [
+ [[link asio.reference.coroutine.is_child [*is_child]]]
+ [Returns true if the coroutine is the child of a fork. ]
+ ]
+
+ [
+ [[link asio.reference.coroutine.is_complete [*is_complete]]]
+ [Returns true if the coroutine has reached its terminal state. ]
+ ]
+
+ [
+ [[link asio.reference.coroutine.is_parent [*is_parent]]]
+ [Returns true if the coroutine is the parent of a fork. ]
+ ]
+
+]
+
+The `coroutine` class may be used to implement stackless coroutines. The class itself is used to store the current state of the coroutine.
+
+Coroutines are copy-constructible and assignable, and the space overhead is a single int. They can be used as a base class:
+
+
+
+ class session : coroutine
+ {
+ ...
+ };
+
+
+
+
+or as a data member:
+
+
+
+ class session
+ {
+ ...
+ coroutine coro_;
+ };
+
+
+
+
+or even bound in as a function argument using lambdas or `bind()`. The important thing is that as the application maintains a copy of the object for as long as the coroutine must be kept alive.
+
+
+[heading Pseudo-keywords]
+
+
+
+A coroutine is used in conjunction with certain "pseudo-keywords", which are implemented as macros. These macros are defined by a header file:
+
+
+
+ #include <asio/yield.hpp>
+
+
+
+
+and may conversely be undefined as follows:
+
+
+
+ #include <asio/unyield.hpp>
+
+
+
+
+[*reenter]
+
+The `reenter` macro is used to define the body of a coroutine. It takes a single argument: a pointer or reference to a coroutine object. For example, if the base class is a coroutine object you may write:
+
+
+
+ reenter (this)
+ {
+ ... coroutine body ...
+ }
+
+
+
+
+and if a data member or other variable you can write:
+
+
+
+ reenter (coro_)
+ {
+ ... coroutine body ...
+ }
+
+
+
+
+When `reenter` is executed at runtime, control jumps to the location of the last `yield` or `fork`.
+
+The coroutine body may also be a single statement, such as:
+
+
+
+ reenter (this) for (;;)
+ {
+ ...
+ }
+
+
+
+
+[*Limitation:] The `reenter` macro is implemented using a switch. This means that you must take care when using local variables within the coroutine body. The local variable is not allowed in a position where reentering the coroutine could bypass the variable definition.
+
+[*yield ['statement]]
+
+This form of the `yield` keyword is often used with asynchronous operations:
+
+
+
+ yield socket_->async_read_some(buffer(*buffer_), *this);
+
+
+
+
+This divides into four logical steps:
+
+
+* `yield` saves the current state of the coroutine.
+
+* The statement initiates the asynchronous operation.
+
+* The resume point is defined immediately following the statement.
+
+* Control is transferred to the end of the coroutine body.
+
+When the asynchronous operation completes, the function object is invoked and `reenter` causes control to transfer to the resume point. It is important to remember to carry the coroutine state forward with the asynchronous operation. In the above snippet, the current class is a function object object with a coroutine object as base class or data member.
+
+The statement may also be a compound statement, and this permits us to define local variables with limited scope:
+
+
+
+ yield
+ {
+ mutable_buffers_1 b = buffer(*buffer_);
+ socket_->async_read_some(b, *this);
+ }
+
+
+
+
+[*yield return ['expression] ;]
+
+This form of `yield` is often used in generators or coroutine-based parsers. For example, the function object:
+
+
+
+ struct interleave : coroutine
+ {
+ istream& is1;
+ istream& is2;
+ char operator()(char c)
+ {
+ reenter (this) for (;;)
+ {
+ yield return is1.get();
+ yield return is2.get();
+ }
+ }
+ };
+
+
+
+
+defines a trivial coroutine that interleaves the characters from two input streams.
+
+This type of `yield` divides into three logical steps:
+
+
+* `yield` saves the current state of the coroutine.
+
+* The resume point is defined immediately following the semicolon.
+
+* The value of the expression is returned from the function.
+
+[*yield ;]
+
+This form of `yield` is equivalent to the following steps:
+
+
+* `yield` saves the current state of the coroutine.
+
+* The resume point is defined immediately following the semicolon.
+
+* Control is transferred to the end of the coroutine body.
+
+This form might be applied when coroutines are used for cooperative threading and scheduling is explicitly managed. For example:
+
+
+
+ struct task : coroutine
+ {
+ ...
+ void operator()()
+ {
+ reenter (this)
+ {
+ while (... not finished ...)
+ {
+ ... do something ...
+ yield;
+ ... do some more ...
+ yield;
+ }
+ }
+ }
+ ...
+ };
+ ...
+ task t1, t2;
+ for (;;)
+ {
+ t1();
+ t2();
+ }
+
+
+
+
+[*yield break ;]
+
+The final form of `yield` is used to explicitly terminate the coroutine. This form is comprised of two steps:
+
+
+* `yield` sets the coroutine state to indicate termination.
+
+* Control is transferred to the end of the coroutine body.
+
+Once terminated, calls to `is_complete()` return true and the coroutine cannot be reentered.
+
+Note that a coroutine may also be implicitly terminated if the coroutine body is exited without a yield, e.g. by return, throw or by running to the end of the body.
+
+[*fork ['statement]]
+
+The `fork` pseudo-keyword is used when "forking" a coroutine, i.e. splitting it into two (or more) copies. One use of `fork` is in a server, where a new coroutine is created to handle each client connection:
+
+
+
+ reenter (this)
+ {
+ do
+ {
+ socket_.reset(new tcp::socket(io_context_));
+ yield acceptor->async_accept(*socket_, *this);
+ fork server(*this)();
+ } while (is_parent());
+ ... client-specific handling follows ...
+ }
+
+
+
+
+The logical steps involved in a `fork` are:
+
+
+* `fork` saves the current state of the coroutine.
+
+* The statement creates a copy of the coroutine and either executes it immediately or schedules it for later execution.
+
+* The resume point is defined immediately following the semicolon.
+
+* For the "parent", control immediately continues from the next line.
+
+The functions `is_parent()` and `is_child()` can be used to differentiate between parent and child. You would use these functions to alter subsequent control flow.
+
+Note that `fork` doesn't do the actual forking by itself. It is the application's responsibility to create a clone of the coroutine and call it. The clone can be called immediately, as above, or scheduled for delayed execution using something like `io_context::post()`.
+
+
+[heading Alternate macro names]
+
+
+
+If preferred, an application can use macro names that follow a more typical naming convention, rather than the pseudo-keywords. These are:
+
+
+* `ASIO_CORO_REENTER` instead of `reenter`
+
+* `ASIO_CORO_YIELD` instead of `yield`
+
+* `ASIO_CORO_FORK` instead of `fork`
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/coroutine.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:coroutine coroutine::coroutine]
+
+[indexterm2 asio.indexterm.coroutine.coroutine..coroutine..coroutine]
+Constructs a coroutine in its initial state.
+
+
+ coroutine();
+
+
+
+[endsect]
+
+
+
+[section:is_child coroutine::is_child]
+
+[indexterm2 asio.indexterm.coroutine.is_child..is_child..coroutine]
+Returns true if the coroutine is the child of a fork.
+
+
+ bool is_child() const;
+
+
+
+[endsect]
+
+
+
+[section:is_complete coroutine::is_complete]
+
+[indexterm2 asio.indexterm.coroutine.is_complete..is_complete..coroutine]
+Returns true if the coroutine has reached its terminal state.
+
+
+ bool is_complete() const;
+
+
+
+[endsect]
+
+
+
+[section:is_parent coroutine::is_parent]
+
+[indexterm2 asio.indexterm.coroutine.is_parent..is_parent..coroutine]
+Returns true if the coroutine is the parent of a fork.
+
+
+ bool is_parent() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:deadline_timer deadline_timer]
+
+[indexterm1 asio.indexterm.deadline_timer..deadline_timer]
+Typedef for the typical usage of timer. Uses a UTC clock.
+
+
+ typedef basic_deadline_timer< boost::posix_time::ptime > deadline_timer;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.duration_type [*duration_type]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.time_type [*time_type]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_deadline_timer.traits_type [*traits_type]]]
+ [The time traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_deadline_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.basic_deadline_timer [*basic_deadline_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_deadline_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.expires_at [*expires_at]]]
+ [Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.expires_from_now [*expires_from_now]]]
+ [Get the timer's expiry time relative to now.
+
+ Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_deadline_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_deadline_timer._basic_deadline_timer [*~basic_deadline_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_deadline_timer `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 [link asio.reference.deadline_timer `deadline_timer`] typedef.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait:
+
+ // Construct a timer without setting an expiry time.
+ asio::deadline_timer timer(io_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();
+
+
+
+
+
+Performing an asynchronous wait:
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::deadline_timer timer(io_context,
+ boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading 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:
+
+
+
+ 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.
+ }
+ }
+
+
+
+
+
+* 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/deadline_timer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:defer defer]
+
+[indexterm1 asio.indexterm.defer..defer]
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.defer.overload1 defer]``(
+ CompletionToken && token);
+ `` [''''&raquo;''' [link asio.reference.defer.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.defer.overload2 defer]``(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.defer.overload2 more...]]``
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.defer.overload3 defer]``(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.defer.overload3 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/defer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 defer (1 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` defer(
+ CompletionToken && token);
+
+
+This function submits an object for execution using the object's associated executor. The function object is queued for execution, and is never called from the current thread prior to returning from `defer()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex` by performing `get_associated_executor(handler)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Performs `ex.defer(std::move(handler), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 defer (2 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` defer(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+This function submits an object for execution using the specified executor. The function object is queued for execution, and is never called from the current thread prior to returning from `defer()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex1` by performing `get_associated_executor(handler)`.
+
+
+* Creates a work object `w` by performing `make_work(ex1)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Constructs a function object `f` with a function call operator that performs `ex1.dispatch(std::move(handler), alloc)` followed by `w.reset()`.
+
+
+* Performs `Executor(ex).defer(std::move(f), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 defer (3 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` defer(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[heading Return Value]
+
+`defer(ctx.get_executor(), forward<CompletionToken>(token))`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:dispatch dispatch]
+
+[indexterm1 asio.indexterm.dispatch..dispatch]
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.dispatch.overload1 dispatch]``(
+ CompletionToken && token);
+ `` [''''&raquo;''' [link asio.reference.dispatch.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.dispatch.overload2 dispatch]``(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.dispatch.overload2 more...]]``
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.dispatch.overload3 dispatch]``(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.dispatch.overload3 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/dispatch.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 dispatch (1 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` dispatch(
+ CompletionToken && token);
+
+
+This function submits an object for execution using the object's associated executor. The function object is queued for execution, and is never called from the current thread prior to returning from `dispatch()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex` by performing `get_associated_executor(handler)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Performs `ex.dispatch(std::move(handler), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 dispatch (2 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` dispatch(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+This function submits an object for execution using the specified executor. The function object is queued for execution, and is never called from the current thread prior to returning from `dispatch()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex1` by performing `get_associated_executor(handler)`.
+
+
+* Creates a work object `w` by performing `make_work(ex1)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Constructs a function object `f` with a function call operator that performs `ex1.dispatch(std::move(handler), alloc)` followed by `w.reset()`.
+
+
+* Performs `Executor(ex).dispatch(std::move(f), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 dispatch (3 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` dispatch(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[heading Return Value]
+
+`dispatch(ctx.get_executor(), forward<CompletionToken>(token))`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:dynamic_buffer dynamic_buffer]
+
+[indexterm1 asio.indexterm.dynamic_buffer..dynamic_buffer]
+The `asio::dynamic_buffer` function is used to create a dynamically resized buffer from a `std::basic_string` or `std::vector`.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ dynamic_string_buffer< Elem, Traits, Allocator > ``[link asio.reference.dynamic_buffer.overload1 dynamic_buffer]``(
+ std::basic_string< Elem, Traits, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.dynamic_buffer.overload1 more...]]``
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ dynamic_string_buffer< Elem, Traits, Allocator > ``[link asio.reference.dynamic_buffer.overload2 dynamic_buffer]``(
+ std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size);
+ `` [''''&raquo;''' [link asio.reference.dynamic_buffer.overload2 more...]]``
+
+ template<
+ typename Elem,
+ typename Allocator>
+ dynamic_vector_buffer< Elem, Allocator > ``[link asio.reference.dynamic_buffer.overload3 dynamic_buffer]``(
+ std::vector< Elem, Allocator > & data);
+ `` [''''&raquo;''' [link asio.reference.dynamic_buffer.overload3 more...]]``
+
+ template<
+ typename Elem,
+ typename Allocator>
+ dynamic_vector_buffer< Elem, Allocator > ``[link asio.reference.dynamic_buffer.overload4 dynamic_buffer]``(
+ std::vector< Elem, Allocator > & data,
+ std::size_t max_size);
+ `` [''''&raquo;''' [link asio.reference.dynamic_buffer.overload4 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 dynamic_buffer (1 of 4 overloads)]
+
+
+Create a new dynamic buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ dynamic_string_buffer< Elem, Traits, Allocator > dynamic_buffer(
+ std::basic_string< Elem, Traits, Allocator > & data);
+
+
+
+[heading Return Value]
+
+`dynamic_string_buffer<Elem, Traits, Allocator>(data)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 dynamic_buffer (2 of 4 overloads)]
+
+
+Create a new dynamic buffer that represents the given string.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ dynamic_string_buffer< Elem, Traits, Allocator > dynamic_buffer(
+ std::basic_string< Elem, Traits, Allocator > & data,
+ std::size_t max_size);
+
+
+
+[heading Return Value]
+
+`dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 dynamic_buffer (3 of 4 overloads)]
+
+
+Create a new dynamic buffer that represents the given vector.
+
+
+ template<
+ typename Elem,
+ typename Allocator>
+ dynamic_vector_buffer< Elem, Allocator > dynamic_buffer(
+ std::vector< Elem, Allocator > & data);
+
+
+
+[heading Return Value]
+
+`dynamic_vector_buffer<Elem, Allocator>(data)`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 dynamic_buffer (4 of 4 overloads)]
+
+
+Create a new dynamic buffer that represents the given vector.
+
+
+ template<
+ typename Elem,
+ typename Allocator>
+ dynamic_vector_buffer< Elem, Allocator > dynamic_buffer(
+ std::vector< Elem, Allocator > & data,
+ std::size_t max_size);
+
+
+
+[heading Return Value]
+
+`dynamic_vector_buffer<Elem, Allocator>(data, max_size)`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:dynamic_string_buffer dynamic_string_buffer]
+
+
+Adapt a basic\_string to the DynamicBuffer requirements.
+
+
+ template<
+ typename Elem,
+ typename Traits,
+ typename Allocator>
+ class dynamic_string_buffer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.dynamic_string_buffer.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.dynamic_string_buffer.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.capacity [*capacity]]]
+ [Get the current capacity of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.commit [*commit]]]
+ [Move bytes from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.dynamic_string_buffer [*dynamic_string_buffer]]]
+ [Construct a dynamic buffer from a string.
+
+ Move construct a dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.max_size [*max_size]]]
+ [Get the maximum size of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_string_buffer.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+Requires that `sizeof(Elem) == 1`.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:capacity dynamic_string_buffer::capacity]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.capacity..capacity..dynamic_string_buffer]
+Get the current capacity of the dynamic buffer.
+
+
+ std::size_t capacity() const;
+
+
+
+[heading Return Value]
+
+The current total capacity of the buffer, i.e. for both the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:commit dynamic_string_buffer::commit]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.commit..commit..dynamic_string_buffer]
+Move bytes from the output sequence to the input sequence.
+
+
+ void commit(
+ std::size_t n);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[n][The number of bytes to append from the start of the output sequence to the end of the input sequence. The remainder of the output sequence is discarded.]]
+
+]
+
+Requires a preceding call `prepare(x)` where `x >= n`, and no intervening operations that modify the input or output sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the output sequence, the entire output sequence is moved to the input sequence and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:const_buffers_type dynamic_string_buffer::const_buffers_type]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.const_buffers_type..const_buffers_type..dynamic_string_buffer]
+The type used to represent the input sequence as a list of buffers.
+
+
+ typedef const_buffer const_buffers_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.const_buffer [*const_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range.
+
+ Construct a non-modifiable buffer from a modifiable one. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus_ [*operator+]]]
+ [Create a new non-modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.const_buffer `const_buffer`] class provides a safe representation of a buffer that cannot be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::const_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:consume dynamic_string_buffer::consume]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.consume..consume..dynamic_string_buffer]
+Remove characters from the input sequence.
+
+
+ void consume(
+ std::size_t n);
+
+
+Removes `n` characters from the beginning of the input sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the input sequence, the entire input sequence is consumed and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:data dynamic_string_buffer::data]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.data..data..dynamic_string_buffer]
+Get a list of buffers that represents the input sequence.
+
+
+ const_buffers_type data() const;
+
+
+
+[heading Return Value]
+
+An object of type `const_buffers_type` that satisfies ConstBufferSequence requirements, representing the basic\_string memory in input sequence.
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `dynamic_string_buffer` or `basic_string` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+[section:dynamic_string_buffer dynamic_string_buffer::dynamic_string_buffer]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.dynamic_string_buffer..dynamic_string_buffer..dynamic_string_buffer]
+Construct a dynamic buffer from a string.
+
+
+ explicit ``[link asio.reference.dynamic_string_buffer.dynamic_string_buffer.overload1 dynamic_string_buffer]``(
+ std::basic_string< Elem, Traits, Allocator > & s,
+ std::size_t maximum_size = (std::numeric_limits< std::size_t >::max)());
+ `` [''''&raquo;''' [link asio.reference.dynamic_string_buffer.dynamic_string_buffer.overload1 more...]]``
+
+
+Move construct a dynamic buffer.
+
+
+ ``[link asio.reference.dynamic_string_buffer.dynamic_string_buffer.overload2 dynamic_string_buffer]``(
+ dynamic_string_buffer && other);
+ `` [''''&raquo;''' [link asio.reference.dynamic_string_buffer.dynamic_string_buffer.overload2 more...]]``
+
+
+[section:overload1 dynamic_string_buffer::dynamic_string_buffer (1 of 2 overloads)]
+
+
+Construct a dynamic buffer from a string.
+
+
+ dynamic_string_buffer(
+ std::basic_string< Elem, Traits, Allocator > & s,
+ std::size_t maximum_size = (std::numeric_limits< std::size_t >::max)());
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The string to be used as backing storage for the dynamic buffer. Any existing data in the string is treated as the dynamic buffer's input sequence. The object stores a reference to the string and the user is responsible for ensuring that the string object remains valid until the [link asio.reference.dynamic_string_buffer `dynamic_string_buffer`] object is destroyed.]]
+
+[[maximum_size][Specifies a maximum size for the buffer, in bytes. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 dynamic_string_buffer::dynamic_string_buffer (2 of 2 overloads)]
+
+
+Move construct a dynamic buffer.
+
+
+ dynamic_string_buffer(
+ dynamic_string_buffer && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:max_size dynamic_string_buffer::max_size]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.max_size..max_size..dynamic_string_buffer]
+Get the maximum size of the dynamic buffer.
+
+
+ std::size_t max_size() const;
+
+
+
+[heading Return Value]
+
+The allowed maximum of the sum of the sizes of the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:mutable_buffers_type dynamic_string_buffer::mutable_buffers_type]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.mutable_buffers_type..mutable_buffers_type..dynamic_string_buffer]
+The type used to represent the output sequence as a list of buffers.
+
+
+ typedef mutable_buffer mutable_buffers_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.mutable_buffer [*mutable_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.mutable_buffer `mutable_buffer`] class provides a safe representation of a buffer that can be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:prepare dynamic_string_buffer::prepare]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.prepare..prepare..dynamic_string_buffer]
+Get a list of buffers that represents the output sequence, with the given size.
+
+
+ mutable_buffers_type prepare(
+ std::size_t n);
+
+
+Ensures that the output sequence can accommodate `n` bytes, resizing the basic\_string object as necessary.
+
+
+[heading Return Value]
+
+An object of type `mutable_buffers_type` that satisfies MutableBufferSequence requirements, representing basic\_string memory at the start of the output sequence of size `n`.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[std::length_error][If `size() + n > max_size()`.]]
+
+]
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `dynamic_string_buffer` or `basic_string` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:size dynamic_string_buffer::size]
+
+[indexterm2 asio.indexterm.dynamic_string_buffer.size..size..dynamic_string_buffer]
+Get the size of the input sequence.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:dynamic_vector_buffer dynamic_vector_buffer]
+
+
+Adapt a vector to the DynamicBuffer requirements.
+
+
+ template<
+ typename Elem,
+ typename Allocator>
+ class dynamic_vector_buffer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.dynamic_vector_buffer.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.dynamic_vector_buffer.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.capacity [*capacity]]]
+ [Get the current capacity of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.commit [*commit]]]
+ [Move bytes from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.dynamic_vector_buffer [*dynamic_vector_buffer]]]
+ [Construct a dynamic buffer from a string.
+
+ Move construct a dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.max_size [*max_size]]]
+ [Get the maximum size of the dynamic buffer. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.dynamic_vector_buffer.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+Requires that `sizeof(Elem) == 1`.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:capacity dynamic_vector_buffer::capacity]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.capacity..capacity..dynamic_vector_buffer]
+Get the current capacity of the dynamic buffer.
+
+
+ std::size_t capacity() const;
+
+
+
+[heading Return Value]
+
+The current total capacity of the buffer, i.e. for both the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:commit dynamic_vector_buffer::commit]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.commit..commit..dynamic_vector_buffer]
+Move bytes from the output sequence to the input sequence.
+
+
+ void commit(
+ std::size_t n);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[n][The number of bytes to append from the start of the output sequence to the end of the input sequence. The remainder of the output sequence is discarded.]]
+
+]
+
+Requires a preceding call `prepare(x)` where `x >= n`, and no intervening operations that modify the input or output sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the output sequence, the entire output sequence is moved to the input sequence and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:const_buffers_type dynamic_vector_buffer::const_buffers_type]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.const_buffers_type..const_buffers_type..dynamic_vector_buffer]
+The type used to represent the input sequence as a list of buffers.
+
+
+ typedef const_buffer const_buffers_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.const_buffer [*const_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range.
+
+ Construct a non-modifiable buffer from a modifiable one. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.const_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.const_buffer.operator_plus_ [*operator+]]]
+ [Create a new non-modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.const_buffer `const_buffer`] class provides a safe representation of a buffer that cannot be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::const_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:consume dynamic_vector_buffer::consume]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.consume..consume..dynamic_vector_buffer]
+Remove characters from the input sequence.
+
+
+ void consume(
+ std::size_t n);
+
+
+Removes `n` characters from the beginning of the input sequence.
+
+
+[heading Remarks]
+
+If `n` is greater than the size of the input sequence, the entire input sequence is consumed and no error is issued.
+
+
+
+
+[endsect]
+
+
+
+[section:data dynamic_vector_buffer::data]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.data..data..dynamic_vector_buffer]
+Get a list of buffers that represents the input sequence.
+
+
+ const_buffers_type data() const;
+
+
+
+[heading Return Value]
+
+An object of type `const_buffers_type` that satisfies ConstBufferSequence requirements, representing the basic\_string memory in input sequence.
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `dynamic_vector_buffer` or `basic_string` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+[section:dynamic_vector_buffer dynamic_vector_buffer::dynamic_vector_buffer]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.dynamic_vector_buffer..dynamic_vector_buffer..dynamic_vector_buffer]
+Construct a dynamic buffer from a string.
+
+
+ explicit ``[link asio.reference.dynamic_vector_buffer.dynamic_vector_buffer.overload1 dynamic_vector_buffer]``(
+ std::vector< Elem, Allocator > & v,
+ std::size_t maximum_size = (std::numeric_limits< std::size_t >::max)());
+ `` [''''&raquo;''' [link asio.reference.dynamic_vector_buffer.dynamic_vector_buffer.overload1 more...]]``
+
+
+Move construct a dynamic buffer.
+
+
+ ``[link asio.reference.dynamic_vector_buffer.dynamic_vector_buffer.overload2 dynamic_vector_buffer]``(
+ dynamic_vector_buffer && other);
+ `` [''''&raquo;''' [link asio.reference.dynamic_vector_buffer.dynamic_vector_buffer.overload2 more...]]``
+
+
+[section:overload1 dynamic_vector_buffer::dynamic_vector_buffer (1 of 2 overloads)]
+
+
+Construct a dynamic buffer from a string.
+
+
+ dynamic_vector_buffer(
+ std::vector< Elem, Allocator > & v,
+ std::size_t maximum_size = (std::numeric_limits< std::size_t >::max)());
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[v][The vector to be used as backing storage for the dynamic buffer. Any existing data in the vector is treated as the dynamic buffer's input sequence. The object stores a reference to the vector and the user is responsible for ensuring that the vector object remains valid until the [link asio.reference.dynamic_vector_buffer `dynamic_vector_buffer`] object is destroyed.]]
+
+[[maximum_size][Specifies a maximum size for the buffer, in bytes. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 dynamic_vector_buffer::dynamic_vector_buffer (2 of 2 overloads)]
+
+
+Move construct a dynamic buffer.
+
+
+ dynamic_vector_buffer(
+ dynamic_vector_buffer && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:max_size dynamic_vector_buffer::max_size]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.max_size..max_size..dynamic_vector_buffer]
+Get the maximum size of the dynamic buffer.
+
+
+ std::size_t max_size() const;
+
+
+
+[heading Return Value]
+
+The allowed maximum of the sum of the sizes of the input sequence and output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:mutable_buffers_type dynamic_vector_buffer::mutable_buffers_type]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.mutable_buffers_type..mutable_buffers_type..dynamic_vector_buffer]
+The type used to represent the output sequence as a list of buffers.
+
+
+ typedef mutable_buffer mutable_buffers_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.mutable_buffer [*mutable_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.mutable_buffer `mutable_buffer`] class provides a safe representation of a buffer that can be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:prepare dynamic_vector_buffer::prepare]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.prepare..prepare..dynamic_vector_buffer]
+Get a list of buffers that represents the output sequence, with the given size.
+
+
+ mutable_buffers_type prepare(
+ std::size_t n);
+
+
+Ensures that the output sequence can accommodate `n` bytes, resizing the basic\_string object as necessary.
+
+
+[heading Return Value]
+
+An object of type `mutable_buffers_type` that satisfies MutableBufferSequence requirements, representing basic\_string memory at the start of the output sequence of size `n`.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[std::length_error][If `size() + n > max_size()`.]]
+
+]
+
+
+[heading Remarks]
+
+The returned object is invalidated by any `dynamic_vector_buffer` or `basic_string` member function that modifies the input sequence or output sequence.
+
+
+
+
+[endsect]
+
+
+
+[section:size dynamic_vector_buffer::size]
+
+[indexterm2 asio.indexterm.dynamic_vector_buffer.size..size..dynamic_vector_buffer]
+Get the size of the input sequence.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:error__addrinfo_category error::addrinfo_category]
+
+[indexterm1 asio.indexterm.error__addrinfo_category..error::addrinfo_category]
+
+ static const asio::error_category & addrinfo_category = asio::error::get_addrinfo_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__addrinfo_errors error::addrinfo_errors]
+
+[indexterm1 asio.indexterm.error__addrinfo_errors..error::addrinfo_errors]
+
+ enum addrinfo_errors
+
+[indexterm2 asio.indexterm.error__addrinfo_errors.service_not_found..service_not_found..error::addrinfo_errors]
+[indexterm2 asio.indexterm.error__addrinfo_errors.socket_type_not_supported..socket_type_not_supported..error::addrinfo_errors]
+
+[heading Values]
+[variablelist
+
+ [
+ [service_not_found]
+ [The service is not supported for the given socket type. ]
+ ]
+
+ [
+ [socket_type_not_supported]
+ [The socket type is not supported. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__basic_errors error::basic_errors]
+
+[indexterm1 asio.indexterm.error__basic_errors..error::basic_errors]
+
+ enum basic_errors
+
+[indexterm2 asio.indexterm.error__basic_errors.access_denied..access_denied..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.address_family_not_supported..address_family_not_supported..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.address_in_use..address_in_use..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.already_connected..already_connected..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.already_started..already_started..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.broken_pipe..broken_pipe..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.connection_aborted..connection_aborted..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.connection_refused..connection_refused..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.connection_reset..connection_reset..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.bad_descriptor..bad_descriptor..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.fault..fault..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.host_unreachable..host_unreachable..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.in_progress..in_progress..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.interrupted..interrupted..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.invalid_argument..invalid_argument..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.message_size..message_size..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.name_too_long..name_too_long..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.network_down..network_down..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.network_reset..network_reset..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.network_unreachable..network_unreachable..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_descriptors..no_descriptors..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_buffer_space..no_buffer_space..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_memory..no_memory..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_permission..no_permission..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_protocol_option..no_protocol_option..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.no_such_device..no_such_device..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.not_connected..not_connected..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.not_socket..not_socket..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.operation_aborted..operation_aborted..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.operation_not_supported..operation_not_supported..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.shut_down..shut_down..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.timed_out..timed_out..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.try_again..try_again..error::basic_errors]
+[indexterm2 asio.indexterm.error__basic_errors.would_block..would_block..error::basic_errors]
+
+[heading Values]
+[variablelist
+
+ [
+ [access_denied]
+ [Permission denied. ]
+ ]
+
+ [
+ [address_family_not_supported]
+ [Address family not supported by protocol. ]
+ ]
+
+ [
+ [address_in_use]
+ [Address already in use. ]
+ ]
+
+ [
+ [already_connected]
+ [Transport endpoint is already connected. ]
+ ]
+
+ [
+ [already_started]
+ [Operation already in progress. ]
+ ]
+
+ [
+ [broken_pipe]
+ [Broken pipe. ]
+ ]
+
+ [
+ [connection_aborted]
+ [A connection has been aborted. ]
+ ]
+
+ [
+ [connection_refused]
+ [Connection refused. ]
+ ]
+
+ [
+ [connection_reset]
+ [Connection reset by peer. ]
+ ]
+
+ [
+ [bad_descriptor]
+ [Bad file descriptor. ]
+ ]
+
+ [
+ [fault]
+ [Bad address. ]
+ ]
+
+ [
+ [host_unreachable]
+ [No route to host. ]
+ ]
+
+ [
+ [in_progress]
+ [Operation now in progress. ]
+ ]
+
+ [
+ [interrupted]
+ [Interrupted system call. ]
+ ]
+
+ [
+ [invalid_argument]
+ [Invalid argument. ]
+ ]
+
+ [
+ [message_size]
+ [Message too long. ]
+ ]
+
+ [
+ [name_too_long]
+ [The name was too long. ]
+ ]
+
+ [
+ [network_down]
+ [Network is down. ]
+ ]
+
+ [
+ [network_reset]
+ [Network dropped connection on reset. ]
+ ]
+
+ [
+ [network_unreachable]
+ [Network is unreachable. ]
+ ]
+
+ [
+ [no_descriptors]
+ [Too many open files. ]
+ ]
+
+ [
+ [no_buffer_space]
+ [No buffer space available. ]
+ ]
+
+ [
+ [no_memory]
+ [Cannot allocate memory. ]
+ ]
+
+ [
+ [no_permission]
+ [Operation not permitted. ]
+ ]
+
+ [
+ [no_protocol_option]
+ [Protocol not available. ]
+ ]
+
+ [
+ [no_such_device]
+ [No such device. ]
+ ]
+
+ [
+ [not_connected]
+ [Transport endpoint is not connected. ]
+ ]
+
+ [
+ [not_socket]
+ [Socket operation on non-socket. ]
+ ]
+
+ [
+ [operation_aborted]
+ [Operation cancelled. ]
+ ]
+
+ [
+ [operation_not_supported]
+ [Operation not supported. ]
+ ]
+
+ [
+ [shut_down]
+ [Cannot send after transport endpoint shutdown. ]
+ ]
+
+ [
+ [timed_out]
+ [Connection timed out. ]
+ ]
+
+ [
+ [try_again]
+ [Resource temporarily unavailable. ]
+ ]
+
+ [
+ [would_block]
+ [The socket is marked non-blocking and the requested operation would block. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__get_addrinfo_category error::get_addrinfo_category]
+
+[indexterm1 asio.indexterm.error__get_addrinfo_category..error::get_addrinfo_category]
+
+ const asio::error_category & get_addrinfo_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__get_misc_category error::get_misc_category]
+
+[indexterm1 asio.indexterm.error__get_misc_category..error::get_misc_category]
+
+ const asio::error_category & get_misc_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__get_netdb_category error::get_netdb_category]
+
+[indexterm1 asio.indexterm.error__get_netdb_category..error::get_netdb_category]
+
+ const asio::error_category & get_netdb_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__get_ssl_category error::get_ssl_category]
+
+[indexterm1 asio.indexterm.error__get_ssl_category..error::get_ssl_category]
+
+ const asio::error_category & get_ssl_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:error__get_system_category error::get_system_category]
+
+[indexterm1 asio.indexterm.error__get_system_category..error::get_system_category]
+
+ const asio::error_category & get_system_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:error__make_error_code error::make_error_code]
+
+[indexterm1 asio.indexterm.error__make_error_code..error::make_error_code]
+
+ asio::error_code ``[link asio.reference.error__make_error_code.overload1 make_error_code]``(
+ basic_errors e);
+ `` [''''&raquo;''' [link asio.reference.error__make_error_code.overload1 more...]]``
+
+ asio::error_code ``[link asio.reference.error__make_error_code.overload2 make_error_code]``(
+ netdb_errors e);
+ `` [''''&raquo;''' [link asio.reference.error__make_error_code.overload2 more...]]``
+
+ asio::error_code ``[link asio.reference.error__make_error_code.overload3 make_error_code]``(
+ addrinfo_errors e);
+ `` [''''&raquo;''' [link asio.reference.error__make_error_code.overload3 more...]]``
+
+ asio::error_code ``[link asio.reference.error__make_error_code.overload4 make_error_code]``(
+ misc_errors e);
+ `` [''''&raquo;''' [link asio.reference.error__make_error_code.overload4 more...]]``
+
+ asio::error_code ``[link asio.reference.error__make_error_code.overload5 make_error_code]``(
+ ssl_errors e);
+ `` [''''&raquo;''' [link asio.reference.error__make_error_code.overload5 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 error::make_error_code (1 of 5 overloads)]
+
+
+
+ asio::error_code make_error_code(
+ basic_errors e);
+
+
+
+[endsect]
+
+
+
+[section:overload2 error::make_error_code (2 of 5 overloads)]
+
+
+
+ asio::error_code make_error_code(
+ netdb_errors e);
+
+
+
+[endsect]
+
+
+
+[section:overload3 error::make_error_code (3 of 5 overloads)]
+
+
+
+ asio::error_code make_error_code(
+ addrinfo_errors e);
+
+
+
+[endsect]
+
+
+
+[section:overload4 error::make_error_code (4 of 5 overloads)]
+
+
+
+ asio::error_code make_error_code(
+ misc_errors e);
+
+
+
+[endsect]
+
+
+
+[section:overload5 error::make_error_code (5 of 5 overloads)]
+
+
+
+ asio::error_code make_error_code(
+ ssl_errors e);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:error__misc_category error::misc_category]
+
+[indexterm1 asio.indexterm.error__misc_category..error::misc_category]
+
+ static const asio::error_category & misc_category = asio::error::get_misc_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__misc_errors error::misc_errors]
+
+[indexterm1 asio.indexterm.error__misc_errors..error::misc_errors]
+
+ enum misc_errors
+
+[indexterm2 asio.indexterm.error__misc_errors.already_open..already_open..error::misc_errors]
+[indexterm2 asio.indexterm.error__misc_errors.eof..eof..error::misc_errors]
+[indexterm2 asio.indexterm.error__misc_errors.not_found..not_found..error::misc_errors]
+[indexterm2 asio.indexterm.error__misc_errors.fd_set_failure..fd_set_failure..error::misc_errors]
+
+[heading Values]
+[variablelist
+
+ [
+ [already_open]
+ [Already open. ]
+ ]
+
+ [
+ [eof]
+ [End of file or stream. ]
+ ]
+
+ [
+ [not_found]
+ [Element not found. ]
+ ]
+
+ [
+ [fd_set_failure]
+ [The descriptor cannot fit into the select system call's fd_set. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__netdb_category error::netdb_category]
+
+[indexterm1 asio.indexterm.error__netdb_category..error::netdb_category]
+
+ static const asio::error_category & netdb_category = asio::error::get_netdb_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__netdb_errors error::netdb_errors]
+
+[indexterm1 asio.indexterm.error__netdb_errors..error::netdb_errors]
+
+ enum netdb_errors
+
+[indexterm2 asio.indexterm.error__netdb_errors.host_not_found..host_not_found..error::netdb_errors]
+[indexterm2 asio.indexterm.error__netdb_errors.host_not_found_try_again..host_not_found_try_again..error::netdb_errors]
+[indexterm2 asio.indexterm.error__netdb_errors.no_data..no_data..error::netdb_errors]
+[indexterm2 asio.indexterm.error__netdb_errors.no_recovery..no_recovery..error::netdb_errors]
+
+[heading Values]
+[variablelist
+
+ [
+ [host_not_found]
+ [Host not found (authoritative). ]
+ ]
+
+ [
+ [host_not_found_try_again]
+ [Host not found (non-authoritative). ]
+ ]
+
+ [
+ [no_data]
+ [The query is valid but does not have associated address data. ]
+ ]
+
+ [
+ [no_recovery]
+ [A non-recoverable error occurred. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:error__ssl_category error::ssl_category]
+
+[indexterm1 asio.indexterm.error__ssl_category..error::ssl_category]
+
+ static const asio::error_category & ssl_category = asio::error::get_ssl_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:error__ssl_errors error::ssl_errors]
+
+[indexterm1 asio.indexterm.error__ssl_errors..error::ssl_errors]
+
+ enum ssl_errors
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:error__system_category error::system_category]
+
+[indexterm1 asio.indexterm.error__system_category..error::system_category]
+
+ static const asio::error_category & system_category = asio::error::get_system_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:error_category error_category]
+
+
+Base class for all error categories.
+
+
+ class error_category :
+ noncopyable
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.error_category.message [*message]]]
+ [Returns a string describing the error denoted by value. ]
+ ]
+
+ [
+ [[link asio.reference.error_category.name [*name]]]
+ [Returns a string naming the error gategory. ]
+ ]
+
+ [
+ [[link asio.reference.error_category.operator_not__eq_ [*operator!=]]]
+ [Inequality operator to compare two error categories. ]
+ ]
+
+ [
+ [[link asio.reference.error_category.operator_eq__eq_ [*operator==]]]
+ [Equality operator to compare two error categories. ]
+ ]
+
+ [
+ [[link asio.reference.error_category._error_category [*~error_category]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:message error_category::message]
+
+[indexterm2 asio.indexterm.error_category.message..message..error_category]
+Returns a string describing the error denoted by `value`.
+
+
+ std::string message(
+ int value) const;
+
+
+
+[endsect]
+
+
+
+[section:name error_category::name]
+
+[indexterm2 asio.indexterm.error_category.name..name..error_category]
+Returns a string naming the error gategory.
+
+
+ const char * name() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ error_category::operator!=]
+
+[indexterm2 asio.indexterm.error_category.operator_not__eq_..operator!=..error_category]
+Inequality operator to compare two error categories.
+
+
+ bool operator!=(
+ const error_category & rhs) const;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ error_category::operator==]
+
+[indexterm2 asio.indexterm.error_category.operator_eq__eq_..operator==..error_category]
+Equality operator to compare two error categories.
+
+
+ bool operator==(
+ const error_category & rhs) const;
+
+
+
+[endsect]
+
+
+
+[section:_error_category error_category::~error_category]
+
+[indexterm2 asio.indexterm.error_category._error_category..~error_category..error_category]
+Destructor.
+
+
+ virtual ~error_category();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:error_code error_code]
+
+
+Class to represent an error code value.
+
+
+ class error_code
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.error_code__unspecified_bool_type_t [*unspecified_bool_type_t]]]
+ []
+
+ ]
+
+ [
+
+ [[link asio.reference.error_code.unspecified_bool_type [*unspecified_bool_type]]]
+ []
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.error_code.category [*category]]]
+ [Get the error category. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.error_code [*error_code]]]
+ [Default constructor.
+
+ Construct with specific error code and category.
+
+ Construct from an error code enum. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.message [*message]]]
+ [Get the message associated with the error. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.operator_unspecified_bool_type [*operator unspecified_bool_type]]]
+ [Operator returns non-null if there is a non-success error code. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.operator_not_ [*operator!]]]
+ [Operator to test if the error represents success. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.unspecified_bool_true [*unspecified_bool_true]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.error_code.value [*value]]]
+ [Get the error value. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.error_code.operator_not__eq_ [*operator!=]]]
+ [Inequality operator to compare two error objects. ]
+ ]
+
+ [
+ [[link asio.reference.error_code.operator_eq__eq_ [*operator==]]]
+ [Equality operator to compare two error objects. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:category error_code::category]
+
+[indexterm2 asio.indexterm.error_code.category..category..error_code]
+Get the error category.
+
+
+ const error_category & category() const;
+
+
+
+[endsect]
+
+
+[section:error_code error_code::error_code]
+
+[indexterm2 asio.indexterm.error_code.error_code..error_code..error_code]
+Default constructor.
+
+
+ ``[link asio.reference.error_code.error_code.overload1 error_code]``();
+ `` [''''&raquo;''' [link asio.reference.error_code.error_code.overload1 more...]]``
+
+
+Construct with specific error code and category.
+
+
+ ``[link asio.reference.error_code.error_code.overload2 error_code]``(
+ int v,
+ const error_category & c);
+ `` [''''&raquo;''' [link asio.reference.error_code.error_code.overload2 more...]]``
+
+
+Construct from an error code enum.
+
+
+ template<
+ typename ErrorEnum>
+ ``[link asio.reference.error_code.error_code.overload3 error_code]``(
+ ErrorEnum e);
+ `` [''''&raquo;''' [link asio.reference.error_code.error_code.overload3 more...]]``
+
+
+[section:overload1 error_code::error_code (1 of 3 overloads)]
+
+
+Default constructor.
+
+
+ error_code();
+
+
+
+[endsect]
+
+
+
+[section:overload2 error_code::error_code (2 of 3 overloads)]
+
+
+Construct with specific error code and category.
+
+
+ error_code(
+ int v,
+ const error_category & c);
+
+
+
+[endsect]
+
+
+
+[section:overload3 error_code::error_code (3 of 3 overloads)]
+
+
+Construct from an error code enum.
+
+
+ template<
+ typename ErrorEnum>
+ error_code(
+ ErrorEnum e);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:message error_code::message]
+
+[indexterm2 asio.indexterm.error_code.message..message..error_code]
+Get the message associated with the error.
+
+
+ std::string message() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_unspecified_bool_type error_code::operator unspecified_bool_type]
+
+[indexterm2 asio.indexterm.error_code.operator_unspecified_bool_type..operator unspecified_bool_type..error_code]
+Operator returns non-null if there is a non-success error code.
+
+
+ operator unspecified_bool_type() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not_ error_code::operator!]
+
+[indexterm2 asio.indexterm.error_code.operator_not_..operator!..error_code]
+Operator to test if the error represents success.
+
+
+ bool operator!() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ error_code::operator!=]
+
+[indexterm2 asio.indexterm.error_code.operator_not__eq_..operator!=..error_code]
+Inequality operator to compare two error objects.
+
+
+ friend bool operator!=(
+ const error_code & e1,
+ const error_code & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ error_code::operator==]
+
+[indexterm2 asio.indexterm.error_code.operator_eq__eq_..operator==..error_code]
+Equality operator to compare two error objects.
+
+
+ friend bool operator==(
+ const error_code & e1,
+ const error_code & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:unspecified_bool_true error_code::unspecified_bool_true]
+
+[indexterm2 asio.indexterm.error_code.unspecified_bool_true..unspecified_bool_true..error_code]
+
+ static void unspecified_bool_true(
+ unspecified_bool_type_t );
+
+
+
+[endsect]
+
+
+
+[section:unspecified_bool_type error_code::unspecified_bool_type]
+
+[indexterm2 asio.indexterm.error_code.unspecified_bool_type..unspecified_bool_type..error_code]
+
+ typedef void(*) unspecified_bool_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:value error_code::value]
+
+[indexterm2 asio.indexterm.error_code.value..value..error_code]
+Get the error value.
+
+
+ int value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:error_code__unspecified_bool_type_t error_code::unspecified_bool_type_t]
+
+
+
+ struct unspecified_bool_type_t
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:execution_context execution_context]
+
+
+A context for function object execution.
+
+
+ class execution_context :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.execution_context__id [*id]]]
+ [Class used to uniquely identify a service. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.execution_context__service [*service]]]
+ [Base class for all io_context services. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.execution_context.fork_event [*fork_event]]]
+ [Fork-related event notifications. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context.notify_fork [*notify_fork]]]
+ [Notify the execution_context of a fork-related event. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context.destroy [*destroy]]]
+ [Destroys all services in the context. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context.execution_context [*execution_context]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context.shutdown [*shutdown]]]
+ [Shuts down all services in the context. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context._execution_context [*~execution_context]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context.add_service [*add_service]]]
+ [(Deprecated: Use make_service().) Add a service object to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context.has_service [*has_service]]]
+ [Determine if an execution_context contains a specified service type. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context.make_service [*make_service]]]
+ [Creates a service object and adds it to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context.use_service [*use_service]]]
+ [Obtain the service object corresponding to the given type. ]
+ ]
+
+]
+
+An execution context represents a place where function objects will be executed. An `io_context` is an example of an execution context.
+
+
+[heading The execution_context class and services]
+
+
+
+Class [link asio.reference.execution_context `execution_context`] implements an extensible, type-safe, polymorphic set of services, indexed by service type.
+
+Services exist to manage the resources that are shared across an execution context. For example, timers may be implemented in terms of a single timer queue, and this queue would be stored in a service.
+
+Access to the services of an [link asio.reference.execution_context `execution_context`] is via three function templates, `use_service()`, `add_service()` and `has_service()`.
+
+In a call to `use_service<Service>()`, the type argument chooses a service, making available all members of the named type. If `Service` is not present in an [link asio.reference.execution_context `execution_context`], an object of type `Service` is created and added to the [link asio.reference.execution_context `execution_context`]. A C++ program can check if an [link asio.reference.execution_context `execution_context`] implements a particular service with the function template `has_service<Service>()`.
+
+Service objects may be explicitly added to an [link asio.reference.execution_context `execution_context`] using the function template `add_service<Service>()`. If the `Service` is already present, the [link asio.reference.service_already_exists `service_already_exists`] exception is thrown. If the owner of the service is not the same object as the [link asio.reference.execution_context `execution_context`] parameter, the [link asio.reference.invalid_service_owner `invalid_service_owner`] exception is thrown.
+
+Once a service reference is obtained from an [link asio.reference.execution_context `execution_context`] object by calling `use_service()`, that reference remains usable as long as the owning [link asio.reference.execution_context `execution_context`] object exists.
+
+All service implementations have [link asio.reference.execution_context__service `execution_context::service`] as a public base class. Custom services may be implemented by deriving from this class and then added to an [link asio.reference.execution_context `execution_context`] using the facilities described above.
+
+
+[heading The execution_context as a base class]
+
+
+
+Class [link asio.reference.execution_context `execution_context`] may be used only as a base class for concrete execution context types. The `io_context` is an example of such a derived type.
+
+On destruction, a class that is derived from [link asio.reference.execution_context `execution_context`] must perform `execution_context::shutdown()` followed by `execution_context::destroy()`.
+
+This destruction sequence permits programs to simplify their resource management by using `shared_ptr<>`. Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), a `shared_ptr` to the object would be bound into the handlers for all asynchronous operations associated with it. This works as follows:
+
+
+* When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all `shared_ptr` references to the objects are destroyed.
+
+
+* To shut down the whole program, the [link asio.reference.io_context `io_context`] function stop() is called to terminate any run() calls as soon as possible. The [link asio.reference.io_context `io_context`] destructor calls `shutdown()` and `destroy()` to destroy all pending handlers, causing all `shared_ptr` references to all connection objects to be destroyed.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:add_service execution_context::add_service]
+
+[indexterm2 asio.indexterm.execution_context.add_service..add_service..execution_context]
+(Deprecated: Use `make_service()`.) Add a service object to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend void add_service(
+ execution_context & e,
+ Service * svc);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[svc][The service object. On success, ownership of the service object is transferred to the [link asio.reference.execution_context `execution_context`]. When the [link asio.reference.execution_context `execution_context`] object is destroyed, it will destroy the service object by performing:
+``
+ delete static_cast<execution_context::service*>(svc)
+``
+]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`].]]
+
+[[asio::invalid_service_owner][Thrown if the service's owning [link asio.reference.execution_context `execution_context`] is not the [link asio.reference.execution_context `execution_context`] object specified by the `e` parameter. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:destroy execution_context::destroy]
+
+[indexterm2 asio.indexterm.execution_context.destroy..destroy..execution_context]
+Destroys all services in the context.
+
+
+ void destroy();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order * of the beginning of service object lifetime, performs `delete static_cast<execution_context::service*>(svc)`.
+
+
+
+
+[endsect]
+
+
+
+[section:execution_context execution_context::execution_context]
+
+[indexterm2 asio.indexterm.execution_context.execution_context..execution_context..execution_context]
+Constructor.
+
+
+ execution_context();
+
+
+
+[endsect]
+
+
+
+[section:fork_event execution_context::fork_event]
+
+[indexterm2 asio.indexterm.execution_context.fork_event..fork_event..execution_context]
+Fork-related event notifications.
+
+
+ enum fork_event
+
+[indexterm2 asio.indexterm.execution_context.fork_event.fork_prepare..fork_prepare..execution_context]
+[indexterm2 asio.indexterm.execution_context.fork_event.fork_parent..fork_parent..execution_context]
+[indexterm2 asio.indexterm.execution_context.fork_event.fork_child..fork_child..execution_context]
+
+[heading Values]
+[variablelist
+
+ [
+ [fork_prepare]
+ [Notify the context that the process is about to fork. ]
+ ]
+
+ [
+ [fork_parent]
+ [Notify the context that the process has forked and is the parent. ]
+ ]
+
+ [
+ [fork_child]
+ [Notify the context that the process has forked and is the child. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:has_service execution_context::has_service]
+
+[indexterm2 asio.indexterm.execution_context.has_service..has_service..execution_context]
+Determine if an [link asio.reference.execution_context `execution_context`] contains a specified service type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend bool has_service(
+ execution_context & e);
+
+
+This function is used to determine whether the [link asio.reference.execution_context `execution_context`] contains a service object corresponding to the given service type.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+A boolean indicating whether the [link asio.reference.execution_context `execution_context`] contains the service.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:make_service execution_context::make_service]
+
+[indexterm2 asio.indexterm.execution_context.make_service..make_service..execution_context]
+Creates a service object and adds it to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``,
+ typename... Args>
+ friend Service & make_service(
+ execution_context & e,
+ Args &&... args);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[args][Zero or more arguments to be passed to the service constructor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`]. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:notify_fork execution_context::notify_fork]
+
+[indexterm2 asio.indexterm.execution_context.notify_fork..notify_fork..execution_context]
+Notify the [link asio.reference.execution_context `execution_context`] of a fork-related event.
+
+
+ void notify_fork(
+ fork_event event);
+
+
+This function is used to inform the [link asio.reference.execution_context `execution_context`] that the process is about to fork, or has just forked. This allows the [link asio.reference.execution_context `execution_context`], and the services it contains, to perform any necessary housekeeping to ensure correct operation following a fork.
+
+This function must not be called while any other [link asio.reference.execution_context `execution_context`] function, or any function associated with the execution\_context's derived class, is being called in another thread. It is, however, safe to call this function from within a completion handler, provided no other thread is accessing the [link asio.reference.execution_context `execution_context`] or its derived class.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[event][A fork-related event.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the notification fails the [link asio.reference.execution_context `execution_context`] object should no longer be used and should be destroyed.]]
+
+]
+
+
+[heading Example]
+
+The following code illustrates how to incorporate the `notify_fork()` function:
+
+ my_execution_context.notify_fork(execution_context::fork_prepare);
+ if (fork() == 0)
+ {
+ // This is the child process.
+ my_execution_context.notify_fork(execution_context::fork_child);
+ }
+ else
+ {
+ // This is the parent process.
+ my_execution_context.notify_fork(execution_context::fork_parent);
+ }
+
+
+
+
+
+[heading Remarks]
+
+For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, performs `svc->notify_fork();`. When processing the fork\_prepare event, services are visited in reverse order of the beginning of service object lifetime. Otherwise, services are visited in order of the beginning of service object lifetime.
+
+
+
+
+[endsect]
+
+
+
+[section:shutdown execution_context::shutdown]
+
+[indexterm2 asio.indexterm.execution_context.shutdown..shutdown..execution_context]
+Shuts down all services in the context.
+
+
+ void shutdown();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order of the beginning of service object lifetime, performs `svc->shutdown()`.
+
+
+
+
+[endsect]
+
+
+[section:use_service execution_context::use_service]
+
+[indexterm2 asio.indexterm.execution_context.use_service..use_service..execution_context]
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.execution_context.use_service.overload1 use_service]``(
+ execution_context & e);
+ `` [''''&raquo;''' [link asio.reference.execution_context.use_service.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.execution_context.use_service.overload2 use_service]``(
+ io_context & ioc);
+ `` [''''&raquo;''' [link asio.reference.execution_context.use_service.overload2 more...]]``
+
+
+[section:overload1 execution_context::use_service (1 of 2 overloads)]
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ execution_context & e);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.execution_context `execution_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 execution_context::use_service (2 of 2 overloads)]
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ io_context & ioc);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.io_context `io_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ioc][The [link asio.reference.io_context `io_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+[heading Remarks]
+
+This overload is preserved for backwards compatibility with services that inherit from [link asio.reference.io_context__service `io_context::service`].
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_execution_context execution_context::~execution_context]
+
+[indexterm2 asio.indexterm.execution_context._execution_context..~execution_context..execution_context]
+Destructor.
+
+
+ ~execution_context();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:execution_context__id execution_context::id]
+
+
+Class used to uniquely identify a service.
+
+
+ class id :
+ noncopyable
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context__id.id [*id]]]
+ [Constructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:id execution_context::id::id]
+
+[indexterm2 asio.indexterm.execution_context__id.id..id..execution_context::id]
+Constructor.
+
+
+ id();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:execution_context__service execution_context::service]
+
+
+Base class for all [link asio.reference.io_context `io_context`] services.
+
+
+ class service :
+ noncopyable
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context__service.context [*context]]]
+ [Get the context object that owns the service. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context__service.service [*service]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context__service._service [*~service]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Private Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.execution_context__service.notify_fork [*notify_fork]]]
+ [Handle notification of a fork-related event to perform any necessary housekeeping. ]
+ ]
+
+ [
+ [[link asio.reference.execution_context__service.shutdown [*shutdown]]]
+ [Destroy all user-defined handler objects owned by the service. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context execution_context::service::context]
+
+[indexterm2 asio.indexterm.execution_context__service.context..context..execution_context::service]
+Get the context object that owns the service.
+
+
+ execution_context & context();
+
+
+
+[endsect]
+
+
+
+[section:service execution_context::service::service]
+
+[indexterm2 asio.indexterm.execution_context__service.service..service..execution_context::service]
+Constructor.
+
+
+ service(
+ execution_context & owner);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[owner][The [link asio.reference.execution_context `execution_context`] object that owns the service. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:_service execution_context::service::~service]
+
+[indexterm2 asio.indexterm.execution_context__service._service..~service..execution_context::service]
+Destructor.
+
+
+ virtual ~service();
+
+
+
+[endsect]
+
+
+
+[section:notify_fork execution_context::service::notify_fork]
+
+[indexterm2 asio.indexterm.execution_context__service.notify_fork..notify_fork..execution_context::service]
+Handle notification of a fork-related event to perform any necessary housekeeping.
+
+
+ virtual void notify_fork(
+ execution_context::fork_event event);
+
+
+This function is not a pure virtual so that services only have to implement it if necessary. The default implementation does nothing.
+
+
+[endsect]
+
+
+
+[section:shutdown execution_context::service::shutdown]
+
+[indexterm2 asio.indexterm.execution_context__service.shutdown..shutdown..execution_context::service]
+Destroy all user-defined handler objects owned by the service.
+
+
+ void shutdown();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:executor executor]
+
+
+Polymorphic wrapper for executors.
+
+
+ class executor
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.executor__unspecified_bool_type_t [*unspecified_bool_type_t]]]
+ []
+
+ ]
+
+ [
+
+ [[link asio.reference.executor.unspecified_bool_type [*unspecified_bool_type]]]
+ []
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.executor.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.executor.defer [*defer]]]
+ [Request the executor to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.executor.dispatch [*dispatch]]]
+ [Request the executor to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.executor.executor [*executor]]]
+ [Default constructor.
+
+ Construct from nullptr.
+
+ Copy constructor.
+
+ Move constructor.
+
+ Construct a polymorphic wrapper for the specified executor.
+
+ Allocator-aware constructor to create a polymorphic wrapper for the specified executor. ]
+ ]
+
+ [
+ [[link asio.reference.executor.on_work_finished [*on_work_finished]]]
+ [Inform the executor that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.executor.on_work_started [*on_work_started]]]
+ [Inform the executor that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.executor.operator_unspecified_bool_type [*operator unspecified_bool_type]]]
+ [Operator to test if the executor contains a valid target. ]
+ ]
+
+ [
+ [[link asio.reference.executor.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+
+
+ Assignment operator for nullptr_t.
+
+ Assignment operator to create a polymorphic wrapper for the specified executor. ]
+ ]
+
+ [
+ [[link asio.reference.executor.post [*post]]]
+ [Request the executor to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.executor.target [*target]]]
+ [Obtain a pointer to the target executor object. ]
+ ]
+
+ [
+ [[link asio.reference.executor.target_type [*target_type]]]
+ [Obtain type information for the target executor object. ]
+ ]
+
+ [
+ [[link asio.reference.executor.unspecified_bool_true [*unspecified_bool_true]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.executor._executor [*~executor]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.executor.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.executor.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context executor::context]
+
+[indexterm2 asio.indexterm.executor.context..context..executor]
+Obtain the underlying execution context.
+
+
+ execution_context & context() const;
+
+
+
+[endsect]
+
+
+
+[section:defer executor::defer]
+
+[indexterm2 asio.indexterm.executor.defer..defer..executor]
+Request the executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object is executed according to the rules of the target executor object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch executor::dispatch]
+
+[indexterm2 asio.indexterm.executor.dispatch..dispatch..executor]
+Request the executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object is executed according to the rules of the target executor object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:executor executor::executor]
+
+[indexterm2 asio.indexterm.executor.executor..executor..executor]
+Default constructor.
+
+
+ ``[link asio.reference.executor.executor.overload1 executor]``();
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload1 more...]]``
+
+
+Construct from nullptr.
+
+
+ ``[link asio.reference.executor.executor.overload2 executor]``(
+ nullptr_t );
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.executor.executor.overload3 executor]``(
+ const executor & other);
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload3 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.executor.executor.overload4 executor]``(
+ executor && other);
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload4 more...]]``
+
+
+Construct a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ ``[link asio.reference.executor.executor.overload5 executor]``(
+ Executor e);
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload5 more...]]``
+
+
+Allocator-aware constructor to create a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename Allocator>
+ ``[link asio.reference.executor.executor.overload6 executor]``(
+ allocator_arg_t ,
+ const Allocator & a,
+ Executor e);
+ `` [''''&raquo;''' [link asio.reference.executor.executor.overload6 more...]]``
+
+
+[section:overload1 executor::executor (1 of 6 overloads)]
+
+
+Default constructor.
+
+
+ executor();
+
+
+
+[endsect]
+
+
+
+[section:overload2 executor::executor (2 of 6 overloads)]
+
+
+Construct from nullptr.
+
+
+ executor(
+ nullptr_t );
+
+
+
+[endsect]
+
+
+
+[section:overload3 executor::executor (3 of 6 overloads)]
+
+
+Copy constructor.
+
+
+ executor(
+ const executor & other);
+
+
+
+[endsect]
+
+
+
+[section:overload4 executor::executor (4 of 6 overloads)]
+
+
+Move constructor.
+
+
+ executor(
+ executor && other);
+
+
+
+[endsect]
+
+
+
+[section:overload5 executor::executor (5 of 6 overloads)]
+
+
+Construct a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor(
+ Executor e);
+
+
+
+[endsect]
+
+
+
+[section:overload6 executor::executor (6 of 6 overloads)]
+
+
+Allocator-aware constructor to create a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename Allocator>
+ executor(
+ allocator_arg_t ,
+ const Allocator & a,
+ Executor e);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:on_work_finished executor::on_work_finished]
+
+[indexterm2 asio.indexterm.executor.on_work_finished..on_work_finished..executor]
+Inform the executor that some work is no longer outstanding.
+
+
+ void on_work_finished() const;
+
+
+
+[endsect]
+
+
+
+[section:on_work_started executor::on_work_started]
+
+[indexterm2 asio.indexterm.executor.on_work_started..on_work_started..executor]
+Inform the executor that it has some outstanding work to do.
+
+
+ void on_work_started() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_unspecified_bool_type executor::operator unspecified_bool_type]
+
+[indexterm2 asio.indexterm.executor.operator_unspecified_bool_type..operator unspecified_bool_type..executor]
+Operator to test if the executor contains a valid target.
+
+
+ operator unspecified_bool_type() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ executor::operator!=]
+
+[indexterm2 asio.indexterm.executor.operator_not__eq_..operator!=..executor]
+Compare two executors for inequality.
+
+
+ friend bool operator!=(
+ const executor & a,
+ const executor & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_eq_ executor::operator=]
+
+[indexterm2 asio.indexterm.executor.operator_eq_..operator=..executor]
+Assignment operator.
+
+
+ executor & ``[link asio.reference.executor.operator_eq_.overload1 operator=]``(
+ const executor & other);
+ `` [''''&raquo;''' [link asio.reference.executor.operator_eq_.overload1 more...]]``
+
+
+
+ executor & ``[link asio.reference.executor.operator_eq_.overload2 operator=]``(
+ executor && other);
+ `` [''''&raquo;''' [link asio.reference.executor.operator_eq_.overload2 more...]]``
+
+
+Assignment operator for nullptr\_t.
+
+
+ executor & ``[link asio.reference.executor.operator_eq_.overload3 operator=]``(
+ nullptr_t );
+ `` [''''&raquo;''' [link asio.reference.executor.operator_eq_.overload3 more...]]``
+
+
+Assignment operator to create a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor & ``[link asio.reference.executor.operator_eq_.overload4 operator=]``(
+ Executor && e);
+ `` [''''&raquo;''' [link asio.reference.executor.operator_eq_.overload4 more...]]``
+
+
+[section:overload1 executor::operator= (1 of 4 overloads)]
+
+
+Assignment operator.
+
+
+ executor & operator=(
+ const executor & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 executor::operator= (2 of 4 overloads)]
+
+
+
+ executor & operator=(
+ executor && other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 executor::operator= (3 of 4 overloads)]
+
+
+Assignment operator for nullptr\_t.
+
+
+ executor & operator=(
+ nullptr_t );
+
+
+
+[endsect]
+
+
+
+[section:overload4 executor::operator= (4 of 4 overloads)]
+
+
+Assignment operator to create a polymorphic wrapper for the specified executor.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor & operator=(
+ Executor && e);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq__eq_ executor::operator==]
+
+[indexterm2 asio.indexterm.executor.operator_eq__eq_..operator==..executor]
+Compare two executors for equality.
+
+
+ friend bool operator==(
+ const executor & a,
+ const executor & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:post executor::post]
+
+[indexterm2 asio.indexterm.executor.post..post..executor]
+Request the executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object is executed according to the rules of the target executor object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:target executor::target]
+
+[indexterm2 asio.indexterm.executor.target..target..executor]
+Obtain a pointer to the target executor object.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ Executor * ``[link asio.reference.executor.target.overload1 target]``();
+ `` [''''&raquo;''' [link asio.reference.executor.target.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ const Executor * ``[link asio.reference.executor.target.overload2 target]``() const;
+ `` [''''&raquo;''' [link asio.reference.executor.target.overload2 more...]]``
+
+
+[section:overload1 executor::target (1 of 2 overloads)]
+
+
+Obtain a pointer to the target executor object.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ Executor * target();
+
+
+
+[heading Return Value]
+
+If `target_type() == typeid(T)`, a pointer to the stored executor target; otherwise, a null pointer.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 executor::target (2 of 2 overloads)]
+
+
+Obtain a pointer to the target executor object.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ const Executor * target() const;
+
+
+
+[heading Return Value]
+
+If `target_type() == typeid(T)`, a pointer to the stored executor target; otherwise, a null pointer.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:target_type executor::target_type]
+
+[indexterm2 asio.indexterm.executor.target_type..target_type..executor]
+Obtain type information for the target executor object.
+
+
+ const std::type_info & target_type() const;
+
+
+
+[heading Return Value]
+
+If `*this` has a target type of type `T`, `typeid(T)`; otherwise, `typeid(void)`.
+
+
+
+
+[endsect]
+
+
+
+[section:unspecified_bool_true executor::unspecified_bool_true]
+
+[indexterm2 asio.indexterm.executor.unspecified_bool_true..unspecified_bool_true..executor]
+
+ static void unspecified_bool_true(
+ unspecified_bool_type_t );
+
+
+
+[endsect]
+
+
+
+[section:unspecified_bool_type executor::unspecified_bool_type]
+
+[indexterm2 asio.indexterm.executor.unspecified_bool_type..unspecified_bool_type..executor]
+
+ typedef void(*) unspecified_bool_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:_executor executor::~executor]
+
+[indexterm2 asio.indexterm.executor._executor..~executor..executor]
+Destructor.
+
+
+ ~executor();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:executor__unspecified_bool_type_t executor::unspecified_bool_type_t]
+
+
+
+ struct unspecified_bool_type_t
+
+
+[heading Requirements]
+
+['Header: ][^asio/executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:executor_arg executor_arg]
+
+[indexterm1 asio.indexterm.executor_arg..executor_arg]
+A special value, similar to std::nothrow, used to disambiguate constructors that accept executor arguments.
+
+
+ constexpr executor_arg_t executor_arg;
+
+
+See [link asio.reference.executor_arg_t `executor_arg_t`] and [link asio.reference.uses_executor `uses_executor`] for more information.
+
+[heading Requirements]
+
+['Header: ][^asio/uses_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:executor_arg_t executor_arg_t]
+
+
+A special type, similar to std::nothrow\_t, used to disambiguate constructors that accept executor arguments.
+
+
+ struct executor_arg_t
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.executor_arg_t.executor_arg_t [*executor_arg_t]]]
+ [Constructor. ]
+ ]
+
+]
+
+The [link asio.reference.executor_arg_t `executor_arg_t`] struct is an empty structure type used as a unique type to disambiguate constructor and function overloading. Specifically, some types have constructors with [link asio.reference.executor_arg_t `executor_arg_t`] as the first argument, immediately followed by an argument of a type that satisfies the Executor type requirements.
+
+[heading Requirements]
+
+['Header: ][^asio/uses_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:executor_arg_t executor_arg_t::executor_arg_t]
+
+[indexterm2 asio.indexterm.executor_arg_t.executor_arg_t..executor_arg_t..executor_arg_t]
+Constructor.
+
+
+ constexpr executor_arg_t();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:executor_binder executor_binder]
+
+
+A call wrapper type to bind an executor of type `Executor` to an object of type `T`.
+
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ class executor_binder
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.executor_binder.argument_type [*argument_type]]]
+ [The type of the function's argument. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.executor_binder.executor_type [*executor_type]]]
+ [The type of the associated executor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.executor_binder.first_argument_type [*first_argument_type]]]
+ [The type of the function's first argument. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.executor_binder.result_type [*result_type]]]
+ [The return type if a function. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.executor_binder.second_argument_type [*second_argument_type]]]
+ [The type of the function's second argument. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.executor_binder.target_type [*target_type]]]
+ [The type of the target object. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.executor_binder.executor_binder [*executor_binder]]]
+ [Construct an executor wrapper for the specified object.
+
+ Copy constructor.
+
+ Construct a copy, but specify a different executor.
+
+ Construct a copy of a different executor wrapper type.
+
+ Construct a copy of a different executor wrapper type, but specify a different executor.
+
+ Move constructor.
+
+ Move construct the target object, but specify a different executor.
+
+ Move construct from a different executor wrapper type.
+
+ Move construct from a different executor wrapper type, but specify a different executor. ]
+ ]
+
+ [
+ [[link asio.reference.executor_binder.get [*get]]]
+ [Obtain a reference to the target object. ]
+ ]
+
+ [
+ [[link asio.reference.executor_binder.get_executor [*get_executor]]]
+ [Obtain the associated executor. ]
+ ]
+
+ [
+ [[link asio.reference.executor_binder.operator_lp__rp_ [*operator()]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.executor_binder._executor_binder [*~executor_binder]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:argument_type executor_binder::argument_type]
+
+[indexterm2 asio.indexterm.executor_binder.argument_type..argument_type..executor_binder]
+The type of the function's argument.
+
+
+ typedef see_below argument_type;
+
+
+
+The type of `argument_type` is based on the type `T` of the wrapper's target object:
+
+
+* if `T` is a pointer to a function type accepting a single argument, `argument_type` is a synonym for the return type of `T`;
+
+
+* if `T` is a class type with a member type `argument_type`, then `argument_type` is a synonym for `T::argument_type`;
+
+
+* otherwise `argument_type` is not defined.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:executor_binder executor_binder::executor_binder]
+
+[indexterm2 asio.indexterm.executor_binder.executor_binder..executor_binder..executor_binder]
+Construct an executor wrapper for the specified object.
+
+
+ template<
+ typename U>
+ ``[link asio.reference.executor_binder.executor_binder.overload1 executor_binder]``(
+ executor_arg_t ,
+ const executor_type & e,
+ U && u);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.executor_binder.executor_binder.overload2 executor_binder]``(
+ const executor_binder & other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload2 more...]]``
+
+
+Construct a copy, but specify a different executor.
+
+
+ ``[link asio.reference.executor_binder.executor_binder.overload3 executor_binder]``(
+ executor_arg_t ,
+ const executor_type & e,
+ const executor_binder & other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload3 more...]]``
+
+
+Construct a copy of a different executor wrapper type.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.executor_binder.executor_binder.overload4 executor_binder]``(
+ const executor_binder< U, OtherExecutor > & other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload4 more...]]``
+
+
+Construct a copy of a different executor wrapper type, but specify a different executor.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.executor_binder.executor_binder.overload5 executor_binder]``(
+ executor_arg_t ,
+ const executor_type & e,
+ const executor_binder< U, OtherExecutor > & other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload5 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.executor_binder.executor_binder.overload6 executor_binder]``(
+ executor_binder && other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload6 more...]]``
+
+
+Move construct the target object, but specify a different executor.
+
+
+ ``[link asio.reference.executor_binder.executor_binder.overload7 executor_binder]``(
+ executor_arg_t ,
+ const executor_type & e,
+ executor_binder && other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload7 more...]]``
+
+
+Move construct from a different executor wrapper type.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.executor_binder.executor_binder.overload8 executor_binder]``(
+ executor_binder< U, OtherExecutor > && other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload8 more...]]``
+
+
+Move construct from a different executor wrapper type, but specify a different executor.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.executor_binder.executor_binder.overload9 executor_binder]``(
+ executor_arg_t ,
+ const executor_type & e,
+ executor_binder< U, OtherExecutor > && other);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.executor_binder.overload9 more...]]``
+
+
+[section:overload1 executor_binder::executor_binder (1 of 9 overloads)]
+
+
+Construct an executor wrapper for the specified object.
+
+
+ template<
+ typename U>
+ executor_binder(
+ executor_arg_t ,
+ const executor_type & e,
+ U && u);
+
+
+This constructor is only valid if the type `T` is constructible from type `U`.
+
+
+[endsect]
+
+
+
+[section:overload2 executor_binder::executor_binder (2 of 9 overloads)]
+
+
+Copy constructor.
+
+
+ executor_binder(
+ const executor_binder & other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 executor_binder::executor_binder (3 of 9 overloads)]
+
+
+Construct a copy, but specify a different executor.
+
+
+ executor_binder(
+ executor_arg_t ,
+ const executor_type & e,
+ const executor_binder & other);
+
+
+
+[endsect]
+
+
+
+[section:overload4 executor_binder::executor_binder (4 of 9 overloads)]
+
+
+Construct a copy of a different executor wrapper type.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ executor_binder(
+ const executor_binder< U, OtherExecutor > & other);
+
+
+This constructor is only valid if the `Executor` type is constructible from type `OtherExecutor`, and the type `T` is constructible from type `U`.
+
+
+[endsect]
+
+
+
+[section:overload5 executor_binder::executor_binder (5 of 9 overloads)]
+
+
+Construct a copy of a different executor wrapper type, but specify a different executor.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ executor_binder(
+ executor_arg_t ,
+ const executor_type & e,
+ const executor_binder< U, OtherExecutor > & other);
+
+
+This constructor is only valid if the type `T` is constructible from type `U`.
+
+
+[endsect]
+
+
+
+[section:overload6 executor_binder::executor_binder (6 of 9 overloads)]
+
+
+Move constructor.
+
+
+ executor_binder(
+ executor_binder && other);
+
+
+
+[endsect]
+
+
+
+[section:overload7 executor_binder::executor_binder (7 of 9 overloads)]
+
+
+Move construct the target object, but specify a different executor.
+
+
+ executor_binder(
+ executor_arg_t ,
+ const executor_type & e,
+ executor_binder && other);
+
+
+
+[endsect]
+
+
+
+[section:overload8 executor_binder::executor_binder (8 of 9 overloads)]
+
+
+Move construct from a different executor wrapper type.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ executor_binder(
+ executor_binder< U, OtherExecutor > && other);
+
+
+
+[endsect]
+
+
+
+[section:overload9 executor_binder::executor_binder (9 of 9 overloads)]
+
+
+Move construct from a different executor wrapper type, but specify a different executor.
+
+
+ template<
+ typename U,
+ typename ``[link asio.reference.Executor1 OtherExecutor]``>
+ executor_binder(
+ executor_arg_t ,
+ const executor_type & e,
+ executor_binder< U, OtherExecutor > && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type executor_binder::executor_type]
+
+[indexterm2 asio.indexterm.executor_binder.executor_type..executor_type..executor_binder]
+The type of the associated executor.
+
+
+ typedef Executor executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:first_argument_type executor_binder::first_argument_type]
+
+[indexterm2 asio.indexterm.executor_binder.first_argument_type..first_argument_type..executor_binder]
+The type of the function's first argument.
+
+
+ typedef see_below first_argument_type;
+
+
+
+The type of `first_argument_type` is based on the type `T` of the wrapper's target object:
+
+
+* if `T` is a pointer to a function type accepting two arguments, `first_argument_type` is a synonym for the return type of `T`;
+
+
+* if `T` is a class type with a member type `first_argument_type`, then `first_argument_type` is a synonym for `T::first_argument_type`;
+
+
+* otherwise `first_argument_type` is not defined.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:get executor_binder::get]
+
+[indexterm2 asio.indexterm.executor_binder.get..get..executor_binder]
+Obtain a reference to the target object.
+
+
+ target_type & ``[link asio.reference.executor_binder.get.overload1 get]``();
+ `` [''''&raquo;''' [link asio.reference.executor_binder.get.overload1 more...]]``
+
+ const target_type & ``[link asio.reference.executor_binder.get.overload2 get]``() const;
+ `` [''''&raquo;''' [link asio.reference.executor_binder.get.overload2 more...]]``
+
+
+[section:overload1 executor_binder::get (1 of 2 overloads)]
+
+
+Obtain a reference to the target object.
+
+
+ target_type & get();
+
+
+
+[endsect]
+
+
+
+[section:overload2 executor_binder::get (2 of 2 overloads)]
+
+
+Obtain a reference to the target object.
+
+
+ const target_type & get() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor executor_binder::get_executor]
+
+[indexterm2 asio.indexterm.executor_binder.get_executor..get_executor..executor_binder]
+Obtain the associated executor.
+
+
+ executor_type get_executor() const;
+
+
+
+[endsect]
+
+
+[section:operator_lp__rp_ executor_binder::operator()]
+
+[indexterm2 asio.indexterm.executor_binder.operator_lp__rp_..operator()..executor_binder]
+
+ template<
+ typename... Args>
+ auto ``[link asio.reference.executor_binder.operator_lp__rp_.overload1 operator()]``(
+ Args && ...);
+ `` [''''&raquo;''' [link asio.reference.executor_binder.operator_lp__rp_.overload1 more...]]``
+
+ template<
+ typename... Args>
+ auto ``[link asio.reference.executor_binder.operator_lp__rp_.overload2 operator()]``(
+ Args && ...) const;
+ `` [''''&raquo;''' [link asio.reference.executor_binder.operator_lp__rp_.overload2 more...]]``
+
+
+[section:overload1 executor_binder::operator() (1 of 2 overloads)]
+
+
+
+ template<
+ typename... Args>
+ auto operator()(
+ Args && ...);
+
+
+
+[endsect]
+
+
+
+[section:overload2 executor_binder::operator() (2 of 2 overloads)]
+
+
+
+ template<
+ typename... Args>
+ auto operator()(
+ Args && ...) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:result_type executor_binder::result_type]
+
+[indexterm2 asio.indexterm.executor_binder.result_type..result_type..executor_binder]
+The return type if a function.
+
+
+ typedef see_below result_type;
+
+
+
+The type of `result_type` is based on the type `T` of the wrapper's target object:
+
+
+* if `T` is a pointer to function type, `result_type` is a synonym for the return type of `T`;
+
+
+* if `T` is a class type with a member type `result_type`, then `result_type` is a synonym for `T::result_type`;
+
+
+* otherwise `result_type` is not defined.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:second_argument_type executor_binder::second_argument_type]
+
+[indexterm2 asio.indexterm.executor_binder.second_argument_type..second_argument_type..executor_binder]
+The type of the function's second argument.
+
+
+ typedef see_below second_argument_type;
+
+
+
+The type of `second_argument_type` is based on the type `T` of the wrapper's target object:
+
+
+* if `T` is a pointer to a function type accepting two arguments, `second_argument_type` is a synonym for the return type of `T`;
+
+
+* if `T` is a class type with a member type `first_argument_type`, then `second_argument_type` is a synonym for `T::second_argument_type`;
+
+
+* otherwise `second_argument_type` is not defined.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:target_type executor_binder::target_type]
+
+[indexterm2 asio.indexterm.executor_binder.target_type..target_type..executor_binder]
+The type of the target object.
+
+
+ typedef T target_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/bind_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:_executor_binder executor_binder::~executor_binder]
+
+[indexterm2 asio.indexterm.executor_binder._executor_binder..~executor_binder..executor_binder]
+Destructor.
+
+
+ ~executor_binder();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:executor_work_guard executor_work_guard]
+
+
+An object of type `executor_work_guard` controls ownership of executor work within a scope.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ class executor_work_guard
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.executor_work_guard.executor_type [*executor_type]]]
+ [The underlying executor type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.executor_work_guard.executor_work_guard [*executor_work_guard]]]
+ [Constructs a executor_work_guard object for the specified executor.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.executor_work_guard.get_executor [*get_executor]]]
+ [Obtain the associated executor. ]
+ ]
+
+ [
+ [[link asio.reference.executor_work_guard.owns_work [*owns_work]]]
+ [Whether the executor_work_guard object owns some outstanding work. ]
+ ]
+
+ [
+ [[link asio.reference.executor_work_guard.reset [*reset]]]
+ [Indicate that the work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.executor_work_guard._executor_work_guard [*~executor_work_guard]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/executor_work_guard.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:executor_type executor_work_guard::executor_type]
+
+[indexterm2 asio.indexterm.executor_work_guard.executor_type..executor_type..executor_work_guard]
+The underlying executor type.
+
+
+ typedef Executor executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/executor_work_guard.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:executor_work_guard executor_work_guard::executor_work_guard]
+
+[indexterm2 asio.indexterm.executor_work_guard.executor_work_guard..executor_work_guard..executor_work_guard]
+Constructs a `executor_work_guard` object for the specified executor.
+
+
+ explicit ``[link asio.reference.executor_work_guard.executor_work_guard.overload1 executor_work_guard]``(
+ const executor_type & e);
+ `` [''''&raquo;''' [link asio.reference.executor_work_guard.executor_work_guard.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.executor_work_guard.executor_work_guard.overload2 executor_work_guard]``(
+ const executor_work_guard & other);
+ `` [''''&raquo;''' [link asio.reference.executor_work_guard.executor_work_guard.overload2 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.executor_work_guard.executor_work_guard.overload3 executor_work_guard]``(
+ executor_work_guard && other);
+ `` [''''&raquo;''' [link asio.reference.executor_work_guard.executor_work_guard.overload3 more...]]``
+
+
+[section:overload1 executor_work_guard::executor_work_guard (1 of 3 overloads)]
+
+
+Constructs a `executor_work_guard` object for the specified executor.
+
+
+ executor_work_guard(
+ const executor_type & e);
+
+
+Stores a copy of `e` and calls `on_work_started()` on it.
+
+
+[endsect]
+
+
+
+[section:overload2 executor_work_guard::executor_work_guard (2 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ executor_work_guard(
+ const executor_work_guard & other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 executor_work_guard::executor_work_guard (3 of 3 overloads)]
+
+
+Move constructor.
+
+
+ executor_work_guard(
+ executor_work_guard && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_executor executor_work_guard::get_executor]
+
+[indexterm2 asio.indexterm.executor_work_guard.get_executor..get_executor..executor_work_guard]
+Obtain the associated executor.
+
+
+ executor_type get_executor() const;
+
+
+
+[endsect]
+
+
+
+[section:owns_work executor_work_guard::owns_work]
+
+[indexterm2 asio.indexterm.executor_work_guard.owns_work..owns_work..executor_work_guard]
+Whether the [link asio.reference.executor_work_guard `executor_work_guard`] object owns some outstanding work.
+
+
+ bool owns_work() const;
+
+
+
+[endsect]
+
+
+
+[section:reset executor_work_guard::reset]
+
+[indexterm2 asio.indexterm.executor_work_guard.reset..reset..executor_work_guard]
+Indicate that the work is no longer outstanding.
+
+
+ void reset();
+
+
+
+[endsect]
+
+
+
+[section:_executor_work_guard executor_work_guard::~executor_work_guard]
+
+[indexterm2 asio.indexterm.executor_work_guard._executor_work_guard..~executor_work_guard..executor_work_guard]
+Destructor.
+
+
+ ~executor_work_guard();
+
+
+Unless the object has already been reset, or is in a moved-from state, calls `on_work_finished()` on the stored executor.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:generic__basic_endpoint generic::basic_endpoint]
+
+
+Describes an endpoint for any socket type.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_endpoint
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint from the specified socket address.
+
+ Construct an endpoint from the specific endpoint type.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+The [link asio.reference.generic__basic_endpoint `generic::basic_endpoint`] class template describes an endpoint that may be associated with any socket type.
+
+
+[heading Remarks]
+
+The socket types sockaddr type must be able to fit into a `sockaddr_storage` structure.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_endpoint generic::basic_endpoint::basic_endpoint]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.basic_endpoint..basic_endpoint..generic::basic_endpoint]
+Default constructor.
+
+
+ ``[link asio.reference.generic__basic_endpoint.basic_endpoint.overload1 basic_endpoint]``();
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.basic_endpoint.overload1 more...]]``
+
+
+Construct an endpoint from the specified socket address.
+
+
+ ``[link asio.reference.generic__basic_endpoint.basic_endpoint.overload2 basic_endpoint]``(
+ const void * socket_address,
+ std::size_t socket_address_size,
+ int socket_protocol = 0);
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.basic_endpoint.overload2 more...]]``
+
+
+Construct an endpoint from the specific endpoint type.
+
+
+ template<
+ typename ``[link asio.reference.Endpoint Endpoint]``>
+ ``[link asio.reference.generic__basic_endpoint.basic_endpoint.overload3 basic_endpoint]``(
+ const Endpoint & endpoint);
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.basic_endpoint.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.generic__basic_endpoint.basic_endpoint.overload4 basic_endpoint]``(
+ const basic_endpoint & other);
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.basic_endpoint.overload4 more...]]``
+
+
+[section:overload1 generic::basic_endpoint::basic_endpoint (1 of 4 overloads)]
+
+
+Default constructor.
+
+
+ basic_endpoint();
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::basic_endpoint::basic_endpoint (2 of 4 overloads)]
+
+
+Construct an endpoint from the specified socket address.
+
+
+ basic_endpoint(
+ const void * socket_address,
+ std::size_t socket_address_size,
+ int socket_protocol = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload3 generic::basic_endpoint::basic_endpoint (3 of 4 overloads)]
+
+
+Construct an endpoint from the specific endpoint type.
+
+
+ template<
+ typename ``[link asio.reference.Endpoint Endpoint]``>
+ basic_endpoint(
+ const Endpoint & endpoint);
+
+
+
+[endsect]
+
+
+
+[section:overload4 generic::basic_endpoint::basic_endpoint (4 of 4 overloads)]
+
+
+Copy constructor.
+
+
+ basic_endpoint(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:capacity generic::basic_endpoint::capacity]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.capacity..capacity..generic::basic_endpoint]
+Get the capacity of the endpoint in the native type.
+
+
+ std::size_t capacity() const;
+
+
+
+[endsect]
+
+
+[section:data generic::basic_endpoint::data]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.data..data..generic::basic_endpoint]
+Get the underlying endpoint in the native type.
+
+
+ data_type * ``[link asio.reference.generic__basic_endpoint.data.overload1 data]``();
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.data.overload1 more...]]``
+
+ const data_type * ``[link asio.reference.generic__basic_endpoint.data.overload2 data]``() const;
+ `` [''''&raquo;''' [link asio.reference.generic__basic_endpoint.data.overload2 more...]]``
+
+
+[section:overload1 generic::basic_endpoint::data (1 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ data_type * data();
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::basic_endpoint::data (2 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ const data_type * data() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:data_type generic::basic_endpoint::data_type]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.data_type..data_type..generic::basic_endpoint]
+The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer.
+
+
+ typedef implementation_defined data_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ generic::basic_endpoint::operator!=]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_not__eq_..operator!=..generic::basic_endpoint]
+Compare two endpoints for inequality.
+
+
+ friend bool operator!=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ generic::basic_endpoint::operator<]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_lt_..operator<..generic::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt__eq_ generic::basic_endpoint::operator<=]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_lt__eq_..operator<=..generic::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ generic::basic_endpoint::operator=]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_eq_..operator=..generic::basic_endpoint]
+Assign from another endpoint.
+
+
+ basic_endpoint & operator=(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ generic::basic_endpoint::operator==]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_eq__eq_..operator==..generic::basic_endpoint]
+Compare two endpoints for equality.
+
+
+ friend bool operator==(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ generic::basic_endpoint::operator>]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_gt_..operator>..generic::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ generic::basic_endpoint::operator>=]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.operator_gt__eq_..operator>=..generic::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol generic::basic_endpoint::protocol]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.protocol..protocol..generic::basic_endpoint]
+The protocol associated with the endpoint.
+
+
+ protocol_type protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type generic::basic_endpoint::protocol_type]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.protocol_type..protocol_type..generic::basic_endpoint]
+The protocol type associated with the endpoint.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:resize generic::basic_endpoint::resize]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.resize..resize..generic::basic_endpoint]
+Set the underlying size of the endpoint in the native type.
+
+
+ void resize(
+ std::size_t new_size);
+
+
+
+[endsect]
+
+
+
+[section:size generic::basic_endpoint::size]
+
+[indexterm2 asio.indexterm.generic__basic_endpoint.size..size..generic::basic_endpoint]
+Get the underlying size of the endpoint in the native type.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:generic__datagram_protocol generic::datagram_protocol]
+
+
+Encapsulates the flags needed for a generic datagram-oriented socket.
+
+
+ class datagram_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__datagram_protocol.endpoint [*endpoint]]]
+ [The type of an endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__datagram_protocol.socket [*socket]]]
+ [The generic socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.datagram_protocol [*datagram_protocol]]]
+ [Construct a protocol object for a specific address family and protocol.
+
+ Construct a generic protocol object from a specific protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__datagram_protocol.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.generic__datagram_protocol `generic::datagram_protocol`] class contains flags necessary for datagram-oriented sockets of any address family and protocol.
+
+
+[heading Examples]
+
+Constructing using a native address family and socket protocol:
+
+ datagram_protocol p(AF_INET, IPPROTO_UDP);
+
+
+Constructing from a specific protocol type:
+
+ datagram_protocol p(asio::ip::udp::v4());
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:datagram_protocol generic::datagram_protocol::datagram_protocol]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.datagram_protocol..datagram_protocol..generic::datagram_protocol]
+Construct a protocol object for a specific address family and protocol.
+
+
+ ``[link asio.reference.generic__datagram_protocol.datagram_protocol.overload1 datagram_protocol]``(
+ int address_family,
+ int socket_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__datagram_protocol.datagram_protocol.overload1 more...]]``
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ ``[link asio.reference.generic__datagram_protocol.datagram_protocol.overload2 datagram_protocol]``(
+ const Protocol & source_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__datagram_protocol.datagram_protocol.overload2 more...]]``
+
+
+[section:overload1 generic::datagram_protocol::datagram_protocol (1 of 2 overloads)]
+
+
+Construct a protocol object for a specific address family and protocol.
+
+
+ datagram_protocol(
+ int address_family,
+ int socket_protocol);
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::datagram_protocol::datagram_protocol (2 of 2 overloads)]
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ datagram_protocol(
+ const Protocol & source_protocol);
+
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[@c][bad\_cast Thrown if the source protocol is not datagram-oriented. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:endpoint generic::datagram_protocol::endpoint]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.endpoint..endpoint..generic::datagram_protocol]
+The type of an endpoint.
+
+
+ typedef basic_endpoint< datagram_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint from the specified socket address.
+
+ Construct an endpoint from the specific endpoint type.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+The [link asio.reference.generic__basic_endpoint `generic::basic_endpoint`] class template describes an endpoint that may be associated with any socket type.
+
+
+[heading Remarks]
+
+The socket types sockaddr type must be able to fit into a `sockaddr_storage` structure.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family generic::datagram_protocol::family]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.family..family..generic::datagram_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ generic::datagram_protocol::operator!=]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.operator_not__eq_..operator!=..generic::datagram_protocol]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const datagram_protocol & p1,
+ const datagram_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ generic::datagram_protocol::operator==]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.operator_eq__eq_..operator==..generic::datagram_protocol]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const datagram_protocol & p1,
+ const datagram_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol generic::datagram_protocol::protocol]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.protocol..protocol..generic::datagram_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:socket generic::datagram_protocol::socket]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.socket..socket..generic::datagram_protocol]
+The generic socket type.
+
+
+ typedef basic_datagram_socket< datagram_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.basic_datagram_socket [*basic_datagram_socket]]]
+ [Construct a basic_datagram_socket without opening it.
+
+ Construct and open a basic_datagram_socket.
+
+ Construct a basic_datagram_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_datagram_socket on an existing native socket.
+
+ Move-construct a basic_datagram_socket from another.
+
+ Move-construct a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_datagram_socket from another.
+
+ Move-assign a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive_from [*receive_from]]]
+ [Receive a datagram with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send_to [*send_to]]]
+ [Send a datagram to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket._basic_datagram_socket [*~basic_datagram_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_datagram_socket `basic_datagram_socket`] class template provides asynchronous and blocking datagram-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type generic::datagram_protocol::type]
+
+[indexterm2 asio.indexterm.generic__datagram_protocol.type..type..generic::datagram_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:generic__raw_protocol generic::raw_protocol]
+
+
+Encapsulates the flags needed for a generic raw socket.
+
+
+ class raw_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__raw_protocol.endpoint [*endpoint]]]
+ [The type of an endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__raw_protocol.socket [*socket]]]
+ [The generic socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__raw_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.generic__raw_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__raw_protocol.raw_protocol [*raw_protocol]]]
+ [Construct a protocol object for a specific address family and protocol.
+
+ Construct a generic protocol object from a specific protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__raw_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__raw_protocol.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__raw_protocol.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.generic__raw_protocol `generic::raw_protocol`] class contains flags necessary for raw sockets of any address family and protocol.
+
+
+[heading Examples]
+
+Constructing using a native address family and socket protocol:
+
+ raw_protocol p(AF_INET, IPPROTO_ICMP);
+
+
+Constructing from a specific protocol type:
+
+ raw_protocol p(asio::ip::icmp::v4());
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/raw_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint generic::raw_protocol::endpoint]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.endpoint..endpoint..generic::raw_protocol]
+The type of an endpoint.
+
+
+ typedef basic_endpoint< raw_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint from the specified socket address.
+
+ Construct an endpoint from the specific endpoint type.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+The [link asio.reference.generic__basic_endpoint `generic::basic_endpoint`] class template describes an endpoint that may be associated with any socket type.
+
+
+[heading Remarks]
+
+The socket types sockaddr type must be able to fit into a `sockaddr_storage` structure.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/raw_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family generic::raw_protocol::family]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.family..family..generic::raw_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ generic::raw_protocol::operator!=]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.operator_not__eq_..operator!=..generic::raw_protocol]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const raw_protocol & p1,
+ const raw_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/raw_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ generic::raw_protocol::operator==]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.operator_eq__eq_..operator==..generic::raw_protocol]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const raw_protocol & p1,
+ const raw_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/raw_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol generic::raw_protocol::protocol]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.protocol..protocol..generic::raw_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+[section:raw_protocol generic::raw_protocol::raw_protocol]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.raw_protocol..raw_protocol..generic::raw_protocol]
+Construct a protocol object for a specific address family and protocol.
+
+
+ ``[link asio.reference.generic__raw_protocol.raw_protocol.overload1 raw_protocol]``(
+ int address_family,
+ int socket_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__raw_protocol.raw_protocol.overload1 more...]]``
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ ``[link asio.reference.generic__raw_protocol.raw_protocol.overload2 raw_protocol]``(
+ const Protocol & source_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__raw_protocol.raw_protocol.overload2 more...]]``
+
+
+[section:overload1 generic::raw_protocol::raw_protocol (1 of 2 overloads)]
+
+
+Construct a protocol object for a specific address family and protocol.
+
+
+ raw_protocol(
+ int address_family,
+ int socket_protocol);
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::raw_protocol::raw_protocol (2 of 2 overloads)]
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ raw_protocol(
+ const Protocol & source_protocol);
+
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[@c][bad\_cast Thrown if the source protocol is not raw-oriented. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:socket generic::raw_protocol::socket]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.socket..socket..generic::raw_protocol]
+The generic socket type.
+
+
+ typedef basic_raw_socket< raw_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.basic_raw_socket [*basic_raw_socket]]]
+ [Construct a basic_raw_socket without opening it.
+
+ Construct and open a basic_raw_socket.
+
+ Construct a basic_raw_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_raw_socket on an existing native socket.
+
+ Move-construct a basic_raw_socket from another.
+
+ Move-construct a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_raw_socket from another.
+
+ Move-assign a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive_from [*receive_from]]]
+ [Receive raw data with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send_to [*send_to]]]
+ [Send raw data to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket._basic_raw_socket [*~basic_raw_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_raw_socket `basic_raw_socket`] class template provides asynchronous and blocking raw-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/raw_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type generic::raw_protocol::type]
+
+[indexterm2 asio.indexterm.generic__raw_protocol.type..type..generic::raw_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:generic__seq_packet_protocol generic::seq_packet_protocol]
+
+
+Encapsulates the flags needed for a generic sequenced packet socket.
+
+
+ class seq_packet_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__seq_packet_protocol.endpoint [*endpoint]]]
+ [The type of an endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__seq_packet_protocol.socket [*socket]]]
+ [The generic socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.seq_packet_protocol [*seq_packet_protocol]]]
+ [Construct a protocol object for a specific address family and protocol.
+
+ Construct a generic protocol object from a specific protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__seq_packet_protocol.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.generic__seq_packet_protocol `generic::seq_packet_protocol`] class contains flags necessary for seq\_packet-oriented sockets of any address family and protocol.
+
+
+[heading Examples]
+
+Constructing using a native address family and socket protocol:
+
+ seq_packet_protocol p(AF_INET, IPPROTO_SCTP);
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/seq_packet_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint generic::seq_packet_protocol::endpoint]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.endpoint..endpoint..generic::seq_packet_protocol]
+The type of an endpoint.
+
+
+ typedef basic_endpoint< seq_packet_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint from the specified socket address.
+
+ Construct an endpoint from the specific endpoint type.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+The [link asio.reference.generic__basic_endpoint `generic::basic_endpoint`] class template describes an endpoint that may be associated with any socket type.
+
+
+[heading Remarks]
+
+The socket types sockaddr type must be able to fit into a `sockaddr_storage` structure.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/seq_packet_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family generic::seq_packet_protocol::family]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.family..family..generic::seq_packet_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ generic::seq_packet_protocol::operator!=]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.operator_not__eq_..operator!=..generic::seq_packet_protocol]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const seq_packet_protocol & p1,
+ const seq_packet_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/seq_packet_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ generic::seq_packet_protocol::operator==]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.operator_eq__eq_..operator==..generic::seq_packet_protocol]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const seq_packet_protocol & p1,
+ const seq_packet_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/seq_packet_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol generic::seq_packet_protocol::protocol]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.protocol..protocol..generic::seq_packet_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+[section:seq_packet_protocol generic::seq_packet_protocol::seq_packet_protocol]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.seq_packet_protocol..seq_packet_protocol..generic::seq_packet_protocol]
+Construct a protocol object for a specific address family and protocol.
+
+
+ ``[link asio.reference.generic__seq_packet_protocol.seq_packet_protocol.overload1 seq_packet_protocol]``(
+ int address_family,
+ int socket_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__seq_packet_protocol.seq_packet_protocol.overload1 more...]]``
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ ``[link asio.reference.generic__seq_packet_protocol.seq_packet_protocol.overload2 seq_packet_protocol]``(
+ const Protocol & source_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__seq_packet_protocol.seq_packet_protocol.overload2 more...]]``
+
+
+[section:overload1 generic::seq_packet_protocol::seq_packet_protocol (1 of 2 overloads)]
+
+
+Construct a protocol object for a specific address family and protocol.
+
+
+ seq_packet_protocol(
+ int address_family,
+ int socket_protocol);
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::seq_packet_protocol::seq_packet_protocol (2 of 2 overloads)]
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ seq_packet_protocol(
+ const Protocol & source_protocol);
+
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[@c][bad\_cast Thrown if the source protocol is not based around sequenced packets. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:socket generic::seq_packet_protocol::socket]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.socket..socket..generic::seq_packet_protocol]
+The generic socket type.
+
+
+ typedef basic_seq_packet_socket< seq_packet_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_seq_packet_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.basic_seq_packet_socket [*basic_seq_packet_socket]]]
+ [Construct a basic_seq_packet_socket without opening it.
+
+ Construct and open a basic_seq_packet_socket.
+
+ Construct a basic_seq_packet_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_seq_packet_socket on an existing native socket.
+
+ Move-construct a basic_seq_packet_socket from another.
+
+ Move-construct a basic_seq_packet_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_seq_packet_socket from another.
+
+ Move-assign a basic_seq_packet_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket._basic_seq_packet_socket [*~basic_seq_packet_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_seq_packet_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_seq_packet_socket `basic_seq_packet_socket`] class template provides asynchronous and blocking sequenced packet socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/seq_packet_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type generic::seq_packet_protocol::type]
+
+[indexterm2 asio.indexterm.generic__seq_packet_protocol.type..type..generic::seq_packet_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:generic__stream_protocol generic::stream_protocol]
+
+
+Encapsulates the flags needed for a generic stream-oriented socket.
+
+
+ class stream_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__stream_protocol.endpoint [*endpoint]]]
+ [The type of an endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__stream_protocol.iostream [*iostream]]]
+ [The generic socket iostream type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__stream_protocol.socket [*socket]]]
+ [The generic socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__stream_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.generic__stream_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__stream_protocol.stream_protocol [*stream_protocol]]]
+ [Construct a protocol object for a specific address family and protocol.
+
+ Construct a generic protocol object from a specific protocol. ]
+ ]
+
+ [
+ [[link asio.reference.generic__stream_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__stream_protocol.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__stream_protocol.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.generic__stream_protocol `generic::stream_protocol`] class contains flags necessary for stream-oriented sockets of any address family and protocol.
+
+
+[heading Examples]
+
+Constructing using a native address family and socket protocol:
+
+ stream_protocol p(AF_INET, IPPROTO_TCP);
+
+
+Constructing from a specific protocol type:
+
+ stream_protocol p(asio::ip::tcp::v4());
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint generic::stream_protocol::endpoint]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.endpoint..endpoint..generic::stream_protocol]
+The type of an endpoint.
+
+
+ typedef basic_endpoint< stream_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.generic__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint from the specified socket address.
+
+ Construct an endpoint from the specific endpoint type.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.generic__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+The [link asio.reference.generic__basic_endpoint `generic::basic_endpoint`] class template describes an endpoint that may be associated with any socket type.
+
+
+[heading Remarks]
+
+The socket types sockaddr type must be able to fit into a `sockaddr_storage` structure.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family generic::stream_protocol::family]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.family..family..generic::stream_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:iostream generic::stream_protocol::iostream]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.iostream..iostream..generic::stream_protocol]
+The generic socket iostream type.
+
+
+ typedef basic_socket_iostream< stream_protocol > iostream;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration [*duration]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration_type [*duration_type]]]
+ [(Deprecated: Use duration.) The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_point [*time_point]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_type [*time_type]]]
+ [(Deprecated: Use time_point.) The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_iostream.basic_socket_iostream [*basic_socket_iostream]]]
+ [Construct a basic_socket_iostream without establishing a connection.
+
+ Construct a basic_socket_iostream from the supplied socket.
+
+ Move-construct a basic_socket_iostream from another.
+
+ Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.close [*close]]]
+ [Close the connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.connect [*connect]]]
+ [Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.error [*error]]]
+ [Get the last error associated with the stream. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_after [*expires_after]]]
+ [Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time as an absolute time.
+
+ Set the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expiry [*expiry]]]
+ [Get the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_iostream from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.rdbuf [*rdbuf]]]
+ [Return a pointer to the underlying streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.socket [*socket]]]
+ [Get a reference to the underlying socket. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ generic::stream_protocol::operator!=]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.operator_not__eq_..operator!=..generic::stream_protocol]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const stream_protocol & p1,
+ const stream_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ generic::stream_protocol::operator==]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.operator_eq__eq_..operator==..generic::stream_protocol]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const stream_protocol & p1,
+ const stream_protocol & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol generic::stream_protocol::protocol]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.protocol..protocol..generic::stream_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:socket generic::stream_protocol::socket]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.socket..socket..generic::stream_protocol]
+The generic socket type.
+
+
+ typedef basic_stream_socket< stream_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.basic_stream_socket [*basic_stream_socket]]]
+ [Construct a basic_stream_socket without opening it.
+
+ Construct and open a basic_stream_socket.
+
+ Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_stream_socket on an existing native socket.
+
+ Move-construct a basic_stream_socket from another.
+
+ Move-construct a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_stream_socket from another.
+
+ Move-assign a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.read_some [*read_some]]]
+ [Read some data from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.write_some [*write_some]]]
+ [Write some data to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket._basic_stream_socket [*~basic_stream_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_stream_socket `basic_stream_socket`] class template provides asynchronous and blocking stream-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/generic/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:stream_protocol generic::stream_protocol::stream_protocol]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.stream_protocol..stream_protocol..generic::stream_protocol]
+Construct a protocol object for a specific address family and protocol.
+
+
+ ``[link asio.reference.generic__stream_protocol.stream_protocol.overload1 stream_protocol]``(
+ int address_family,
+ int socket_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__stream_protocol.stream_protocol.overload1 more...]]``
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ ``[link asio.reference.generic__stream_protocol.stream_protocol.overload2 stream_protocol]``(
+ const Protocol & source_protocol);
+ `` [''''&raquo;''' [link asio.reference.generic__stream_protocol.stream_protocol.overload2 more...]]``
+
+
+[section:overload1 generic::stream_protocol::stream_protocol (1 of 2 overloads)]
+
+
+Construct a protocol object for a specific address family and protocol.
+
+
+ stream_protocol(
+ int address_family,
+ int socket_protocol);
+
+
+
+[endsect]
+
+
+
+[section:overload2 generic::stream_protocol::stream_protocol (2 of 2 overloads)]
+
+
+Construct a generic protocol object from a specific protocol.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ stream_protocol(
+ const Protocol & source_protocol);
+
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[@c][bad\_cast Thrown if the source protocol is not stream-oriented. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:type generic::stream_protocol::type]
+
+[indexterm2 asio.indexterm.generic__stream_protocol.type..type..generic::stream_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:get_associated_allocator get_associated_allocator]
+
+[indexterm1 asio.indexterm.get_associated_allocator..get_associated_allocator]
+Helper function to obtain an object's associated allocator.
+
+
+ template<
+ typename T>
+ associated_allocator< T >::type ``[link asio.reference.get_associated_allocator.overload1 get_associated_allocator]``(
+ const T & t);
+ `` [''''&raquo;''' [link asio.reference.get_associated_allocator.overload1 more...]]``
+
+ template<
+ typename T,
+ typename Allocator>
+ associated_allocator< T, Allocator >::type ``[link asio.reference.get_associated_allocator.overload2 get_associated_allocator]``(
+ const T & t,
+ const Allocator & a);
+ `` [''''&raquo;''' [link asio.reference.get_associated_allocator.overload2 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/associated_allocator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 get_associated_allocator (1 of 2 overloads)]
+
+
+Helper function to obtain an object's associated allocator.
+
+
+ template<
+ typename T>
+ associated_allocator< T >::type get_associated_allocator(
+ const T & t);
+
+
+
+[heading Return Value]
+
+`associated_allocator<T>::get(t)`
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 get_associated_allocator (2 of 2 overloads)]
+
+
+Helper function to obtain an object's associated allocator.
+
+
+ template<
+ typename T,
+ typename Allocator>
+ associated_allocator< T, Allocator >::type get_associated_allocator(
+ const T & t,
+ const Allocator & a);
+
+
+
+[heading Return Value]
+
+`associated_allocator<T, Allocator>::get(t, a)`
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:get_associated_executor get_associated_executor]
+
+[indexterm1 asio.indexterm.get_associated_executor..get_associated_executor]
+Helper function to obtain an object's associated executor.
+
+
+ template<
+ typename T>
+ associated_executor< T >::type ``[link asio.reference.get_associated_executor.overload1 get_associated_executor]``(
+ const T & t);
+ `` [''''&raquo;''' [link asio.reference.get_associated_executor.overload1 more...]]``
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ associated_executor< T, Executor >::type ``[link asio.reference.get_associated_executor.overload2 get_associated_executor]``(
+ const T & t,
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.get_associated_executor.overload2 more...]]``
+
+ template<
+ typename T,
+ typename ExecutionContext>
+ associated_executor< T, typename ExecutionContext::executor_type >::type ``[link asio.reference.get_associated_executor.overload3 get_associated_executor]``(
+ const T & t,
+ ExecutionContext & ctx,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.get_associated_executor.overload3 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/associated_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 get_associated_executor (1 of 3 overloads)]
+
+
+Helper function to obtain an object's associated executor.
+
+
+ template<
+ typename T>
+ associated_executor< T >::type get_associated_executor(
+ const T & t);
+
+
+
+[heading Return Value]
+
+`associated_executor<T>::get(t)`
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 get_associated_executor (2 of 3 overloads)]
+
+
+Helper function to obtain an object's associated executor.
+
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ associated_executor< T, Executor >::type get_associated_executor(
+ const T & t,
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+
+[heading Return Value]
+
+`associated_executor<T, Executor>::get(t, ex)`
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 get_associated_executor (3 of 3 overloads)]
+
+
+Helper function to obtain an object's associated executor.
+
+
+ template<
+ typename T,
+ typename ExecutionContext>
+ associated_executor< T, typename ExecutionContext::executor_type >::type get_associated_executor(
+ const T & t,
+ ExecutionContext & ctx,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[heading Return Value]
+
+`associated_executor<T, typename ExecutionContext::executor_type>get(t, ctx.get_executor())`
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:handler_type handler_type]
+
+
+(Deprecated: Use two-parameter version of [link asio.reference.async_result `async_result`].) Default handler type traits provided for all completion token types.
+
+
+ template<
+ typename CompletionToken,
+ typename Signature,
+ typename = void>
+ struct handler_type
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.handler_type.type [*type]]]
+ [The handler type for the specific signature. ]
+
+ ]
+
+]
+
+The [link asio.reference.handler_type `handler_type`] traits class is used for determining the concrete handler type to be used for an asynchronous operation. It allows the handler type 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.
+
+[heading Requirements]
+
+['Header: ][^asio/handler_type.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:type handler_type::type]
+
+[indexterm2 asio.indexterm.handler_type.type..type..handler_type]
+The handler type for the specific signature.
+
+
+ typedef conditional< is_same< CompletionToken, typename decay< CompletionToken >::type >::value, decay< CompletionToken >, handler_type< typename decay< CompletionToken >::type, Signature > >::type::type type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/handler_type.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:has_service has_service]
+
+[indexterm1 asio.indexterm.has_service..has_service]
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ bool has_service(
+ execution_context & e);
+
+
+This function is used to determine whether the [link asio.reference.execution_context `execution_context`] contains a service object corresponding to the given service type.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+A boolean indicating whether the [link asio.reference.execution_context `execution_context`] contains the service.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/impl/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:high_resolution_timer high_resolution_timer]
+
+[indexterm1 asio.indexterm.high_resolution_timer..high_resolution_timer]
+Typedef for a timer based on the high resolution clock.
+
+
+ typedef basic_waitable_timer< chrono::high_resolution_clock > high_resolution_timer;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.duration [*duration]]]
+ [The duration type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.time_point [*time_point]]]
+ [The time point type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.traits_type [*traits_type]]]
+ [The wait traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_waitable_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.basic_waitable_timer [*basic_waitable_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_after [*expires_after]]]
+ [Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time.
+
+ (Deprecated: Use non-error_code overload.) Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expiry [*expiry]]]
+ [Get the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer._basic_waitable_timer [*~basic_waitable_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_waitable_timer `basic_waitable_timer`] class template provides the ability to perform a blocking or asynchronous wait for a timer to expire.
+
+A waitable 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 one of the [link asio.reference.steady_timer `steady_timer`], [link asio.reference.system_timer `system_timer`] or [link asio.reference.high_resolution_timer `high_resolution_timer`] typedefs.
+
+
+[heading Remarks]
+
+This waitable timer functionality is for use with the C++11 standard library's `<chrono>` facility, or with the Boost.Chrono library.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait (C++11):
+
+ // Construct a timer without setting an expiry time.
+ asio::steady_timer timer(io_context);
+
+ // Set an expiry time relative to now.
+ timer.expires_after(std::chrono::seconds(5));
+
+ // Wait for the timer to expire.
+ timer.wait();
+
+
+
+
+
+Performing an asynchronous wait (C++11):
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::steady_timer timer(io_context,
+ std::chrono::steady_clock::now() + std::chrono::seconds(60));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading Changing an active waitable 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:
+
+
+
+ void on_some_event()
+ {
+ if (my_timer.expires_after(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.
+ }
+ }
+
+
+
+
+
+* The `asio::basic_waitable_timer::expires_after()` 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+
+This typedef uses the C++11 `<chrono>` standard library facility, if available. Otherwise, it may use the Boost.Chrono library. To explicitly utilise Boost.Chrono, use the [link asio.reference.basic_waitable_timer `basic_waitable_timer`] template directly:
+
+ typedef basic_waitable_timer<boost::chrono::high_resolution_clock> timer;
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/high_resolution_timer.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+[section:invalid_service_owner invalid_service_owner]
+
+
+Exception thrown when trying to add a service object to an [link asio.reference.execution_context `execution_context`] where the service has a different owner.
+
+
+ class invalid_service_owner
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.invalid_service_owner.invalid_service_owner [*invalid_service_owner]]]
+ []
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:invalid_service_owner invalid_service_owner::invalid_service_owner]
+
+[indexterm2 asio.indexterm.invalid_service_owner.invalid_service_owner..invalid_service_owner..invalid_service_owner]
+
+ invalid_service_owner();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:io_context io_context]
+
+
+Provides core I/O functionality.
+
+
+ class io_context :
+ public execution_context
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.io_context__executor_type [*executor_type]]]
+ [Executor used to submit functions to an io_context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__service [*service]]]
+ [Base class for all io_context services. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__strand [*strand]]]
+ [Provides serialised handler execution. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__work [*work]]]
+ [(Deprecated: Use executor_work_guard.) Class to inform the io_context when it has work to do. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context.count_type [*count_type]]]
+ [The type used to count the number of handlers executed by the context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context.fork_event [*fork_event]]]
+ [Fork-related event notifications. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.dispatch [*dispatch]]]
+ [(Deprecated: Use asio::dispatch().) Request the io_context to invoke the given handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.get_executor [*get_executor]]]
+ [Obtains the executor associated with the io_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.io_context [*io_context]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.notify_fork [*notify_fork]]]
+ [Notify the execution_context of a fork-related event. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.poll [*poll]]]
+ [Run the io_context object's event processing loop to execute ready handlers.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop to execute ready handlers. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.poll_one [*poll_one]]]
+ [Run the io_context object's event processing loop to execute one ready handler.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop to execute one ready handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.post [*post]]]
+ [(Deprecated: Use asio::post().) Request the io_context to invoke the given handler and return immediately. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.reset [*reset]]]
+ [(Deprecated: Use restart().) Reset the io_context in preparation for a subsequent run() invocation. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.restart [*restart]]]
+ [Restart the io_context in preparation for a subsequent run() invocation. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run [*run]]]
+ [Run the io_context object's event processing loop.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_for [*run_for]]]
+ [Run the io_context object's event processing loop for a specified duration. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one [*run_one]]]
+ [Run the io_context object's event processing loop to execute at most one handler.
+
+ (Deprecated: Use non-error_code overlaod.) Run the io_context object's event processing loop to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one_for [*run_one_for]]]
+ [Run the io_context object's event processing loop for a specified duration to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one_until [*run_one_until]]]
+ [Run the io_context object's event processing loop until a specified time to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_until [*run_until]]]
+ [Run the io_context object's event processing loop until a specified time. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.stop [*stop]]]
+ [Stop the io_context object's event processing loop. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.stopped [*stopped]]]
+ [Determine whether the io_context object has been stopped. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.wrap [*wrap]]]
+ [(Deprecated: Use asio::bind_executor().) Create a new handler that automatically dispatches the wrapped handler on the io_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context._io_context [*~io_context]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.destroy [*destroy]]]
+ [Destroys all services in the context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.shutdown [*shutdown]]]
+ [Shuts down all services in the context. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.add_service [*add_service]]]
+ [(Deprecated: Use make_service().) Add a service object to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.has_service [*has_service]]]
+ [Determine if an execution_context contains a specified service type. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.make_service [*make_service]]]
+ [Creates a service object and adds it to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.use_service [*use_service]]]
+ [
+
+ Obtain the service object corresponding to the given type. ]
+ ]
+
+]
+
+The [link asio.reference.io_context `io_context`] class provides the core I/O functionality for users of the asynchronous I/O objects, including:
+
+
+* `asio::ip::tcp::socket`
+
+* `asio::ip::tcp::acceptor`
+
+* `asio::ip::udp::socket`
+
+* [link asio.reference.deadline_timer `deadline_timer`].
+
+The [link asio.reference.io_context `io_context`] class also includes facilities intended for developers of custom asynchronous services.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe, with the specific exceptions of the `restart()` and `notify_fork()` functions. Calling `restart()` while there are unfinished `run()`, `run_one()`, `poll()` or `poll_one()` calls results in undefined behaviour. The `notify_fork()` function should not be called while any [link asio.reference.io_context `io_context`] function, or any function on an I/O object that is associated with the [link asio.reference.io_context `io_context`], is being called in another thread.
+
+
+
+[heading Synchronous and asynchronous operations]
+
+
+
+Synchronous operations on I/O objects implicitly run the [link asio.reference.io_context `io_context`] object for an individual operation. The [link asio.reference.io_context `io_context`] functions `run()`, `run_one()`, `poll()` or `poll_one()` must be called for the [link asio.reference.io_context `io_context`] to perform asynchronous operations on behalf of a C++ program. Notification that an asynchronous operation has completed is delivered by invocation of the associated handler. Handlers are invoked only by a thread that is currently calling any overload of `run()`, `run_one()`, `poll()` or `poll_one()` for the [link asio.reference.io_context `io_context`].
+
+
+[heading Effect of exceptions thrown from handlers]
+
+
+
+If an exception is thrown from a handler, the exception is allowed to propagate through the throwing thread's invocation of `run()`, `run_one()`, `poll()` or `poll_one()`. No other threads that are calling any of these functions are affected. It is then the responsibility of the application to catch the exception.
+
+After the exception has been caught, the `run()`, `run_one()`, `poll()` or `poll_one()` call may be restarted ['without] the need for an intervening call to `restart()`. This allows the thread to rejoin the [link asio.reference.io_context `io_context`] object's thread pool without impacting any other threads in the pool.
+
+For example:
+
+
+
+ asio::io_context io_context;
+ ...
+ for (;;)
+ {
+ try
+ {
+ io_context.run();
+ break; // run() exited normally
+ }
+ catch (my_exception& e)
+ {
+ // Deal with exception as appropriate.
+ }
+ }
+
+
+
+
+
+[heading Stopping the io_context from running out of work]
+
+
+
+Some applications may need to prevent an [link asio.reference.io_context `io_context`] object's `run()` call from returning when there is no more work to do. For example, the [link asio.reference.io_context `io_context`] may be being run in a background thread that is launched prior to the application's asynchronous operations. The `run()` call may be kept running by creating an object of type asio::executor\_work\_guard<io\_context::executor\_type>:
+
+
+
+ asio::io_context io_context;
+ asio::executor_work_guard<asio::io_context::executor_type>
+ = asio::make_work_guard(io_context);
+ ...
+
+
+
+
+To effect a shutdown, the application will then need to call the [link asio.reference.io_context `io_context`] object's `stop()` member function. This will cause the [link asio.reference.io_context `io_context`] `run()` call to return as soon as possible, abandoning unfinished operations and without permitting ready handlers to be dispatched.
+
+Alternatively, if the application requires that all operations and handlers be allowed to finish normally, the work object may be explicitly reset.
+
+
+
+ asio::io_context io_context;
+ asio::executor_work_guard<asio::io_context::executor_type>
+ = asio::make_work_guard(io_context);
+ ...
+ work.reset(); // Allow run() to exit.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:add_service io_context::add_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.add_service..add_service..io_context]
+(Deprecated: Use `make_service()`.) Add a service object to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend void add_service(
+ execution_context & e,
+ Service * svc);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[svc][The service object. On success, ownership of the service object is transferred to the [link asio.reference.execution_context `execution_context`]. When the [link asio.reference.execution_context `execution_context`] object is destroyed, it will destroy the service object by performing:
+``
+ delete static_cast<execution_context::service*>(svc)
+``
+]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`].]]
+
+[[asio::invalid_service_owner][Thrown if the service's owning [link asio.reference.execution_context `execution_context`] is not the [link asio.reference.execution_context `execution_context`] object specified by the `e` parameter. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:count_type io_context::count_type]
+
+[indexterm2 asio.indexterm.io_context.count_type..count_type..io_context]
+The type used to count the number of handlers executed by the context.
+
+
+ typedef std::size_t count_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:destroy io_context::destroy]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.destroy..destroy..io_context]
+Destroys all services in the context.
+
+
+ void destroy();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order * of the beginning of service object lifetime, performs `delete static_cast<execution_context::service*>(svc)`.
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch io_context::dispatch]
+
+[indexterm2 asio.indexterm.io_context.dispatch..dispatch..io_context]
+(Deprecated: Use [link asio.reference.dispatch `dispatch`].) Request the [link asio.reference.io_context `io_context`] to invoke the given handler.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` dispatch(
+ CompletionHandler && handler);
+
+
+This function is used to ask the [link asio.reference.io_context `io_context`] to execute the given handler.
+
+The [link asio.reference.io_context `io_context`] guarantees that the handler will only be called in a thread in which the `run()`, `run_one()`, `poll()` or `poll_one()` member functions is currently being invoked. The handler may be executed inside this function if the guarantee can be met.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called. The [link asio.reference.io_context `io_context`] will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler();
+``
+]]
+
+]
+
+
+[heading Remarks]
+
+This function throws an exception only if:
+
+
+* the handler's `asio_handler_allocate` function; or
+
+
+* the handler's copy constructor
+
+throws an exception.
+
+
+[endsect]
+
+
+
+[section:fork_event io_context::fork_event]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.fork_event..fork_event..io_context]
+Fork-related event notifications.
+
+
+ enum fork_event
+
+[indexterm2 asio.indexterm.io_context.fork_event.fork_prepare..fork_prepare..io_context]
+[indexterm2 asio.indexterm.io_context.fork_event.fork_parent..fork_parent..io_context]
+[indexterm2 asio.indexterm.io_context.fork_event.fork_child..fork_child..io_context]
+
+[heading Values]
+[variablelist
+
+ [
+ [fork_prepare]
+ [Notify the context that the process is about to fork. ]
+ ]
+
+ [
+ [fork_parent]
+ [Notify the context that the process has forked and is the parent. ]
+ ]
+
+ [
+ [fork_child]
+ [Notify the context that the process has forked and is the child. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:get_executor io_context::get_executor]
+
+[indexterm2 asio.indexterm.io_context.get_executor..get_executor..io_context]
+Obtains the executor associated with the [link asio.reference.io_context `io_context`].
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:has_service io_context::has_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.has_service..has_service..io_context]
+Determine if an [link asio.reference.execution_context `execution_context`] contains a specified service type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend bool has_service(
+ execution_context & e);
+
+
+This function is used to determine whether the [link asio.reference.execution_context `execution_context`] contains a service object corresponding to the given service type.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+A boolean indicating whether the [link asio.reference.execution_context `execution_context`] contains the service.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:io_context io_context::io_context]
+
+[indexterm2 asio.indexterm.io_context.io_context..io_context..io_context]
+Constructor.
+
+
+ ``[link asio.reference.io_context.io_context.overload1 io_context]``();
+ `` [''''&raquo;''' [link asio.reference.io_context.io_context.overload1 more...]]``
+
+ explicit ``[link asio.reference.io_context.io_context.overload2 io_context]``(
+ int concurrency_hint);
+ `` [''''&raquo;''' [link asio.reference.io_context.io_context.overload2 more...]]``
+
+
+[section:overload1 io_context::io_context (1 of 2 overloads)]
+
+
+Constructor.
+
+
+ io_context();
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::io_context (2 of 2 overloads)]
+
+
+Constructor.
+
+
+ io_context(
+ int concurrency_hint);
+
+
+Construct with a hint about the required level of concurrency.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[concurrency_hint][A suggestion to the implementation on how many threads it should allow to run simultaneously. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:make_service io_context::make_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.make_service..make_service..io_context]
+Creates a service object and adds it to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``,
+ typename... Args>
+ friend Service & make_service(
+ execution_context & e,
+ Args &&... args);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[args][Zero or more arguments to be passed to the service constructor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`]. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:notify_fork io_context::notify_fork]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.notify_fork..notify_fork..io_context]
+Notify the [link asio.reference.execution_context `execution_context`] of a fork-related event.
+
+
+ void notify_fork(
+ fork_event event);
+
+
+This function is used to inform the [link asio.reference.execution_context `execution_context`] that the process is about to fork, or has just forked. This allows the [link asio.reference.execution_context `execution_context`], and the services it contains, to perform any necessary housekeeping to ensure correct operation following a fork.
+
+This function must not be called while any other [link asio.reference.execution_context `execution_context`] function, or any function associated with the execution\_context's derived class, is being called in another thread. It is, however, safe to call this function from within a completion handler, provided no other thread is accessing the [link asio.reference.execution_context `execution_context`] or its derived class.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[event][A fork-related event.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the notification fails the [link asio.reference.execution_context `execution_context`] object should no longer be used and should be destroyed.]]
+
+]
+
+
+[heading Example]
+
+The following code illustrates how to incorporate the `notify_fork()` function:
+
+ my_execution_context.notify_fork(execution_context::fork_prepare);
+ if (fork() == 0)
+ {
+ // This is the child process.
+ my_execution_context.notify_fork(execution_context::fork_child);
+ }
+ else
+ {
+ // This is the parent process.
+ my_execution_context.notify_fork(execution_context::fork_parent);
+ }
+
+
+
+
+
+[heading Remarks]
+
+For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, performs `svc->notify_fork();`. When processing the fork\_prepare event, services are visited in reverse order of the beginning of service object lifetime. Otherwise, services are visited in order of the beginning of service object lifetime.
+
+
+
+
+[endsect]
+
+
+[section:poll io_context::poll]
+
+[indexterm2 asio.indexterm.io_context.poll..poll..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute ready handlers.
+
+
+ count_type ``[link asio.reference.io_context.poll.overload1 poll]``();
+ `` [''''&raquo;''' [link asio.reference.io_context.poll.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute ready handlers.
+
+
+ count_type ``[link asio.reference.io_context.poll.overload2 poll]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.io_context.poll.overload2 more...]]``
+
+
+[section:overload1 io_context::poll (1 of 2 overloads)]
+
+
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute ready handlers.
+
+
+ count_type poll();
+
+
+The `poll()` function runs handlers that are ready to run, without blocking, until the [link asio.reference.io_context `io_context`] has been stopped or there are no more ready handlers.
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::poll (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute ready handlers.
+
+
+ count_type poll(
+ asio::error_code & ec);
+
+
+The `poll()` function runs handlers that are ready to run, without blocking, until the [link asio.reference.io_context `io_context`] has been stopped or there are no more ready handlers.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:poll_one io_context::poll_one]
+
+[indexterm2 asio.indexterm.io_context.poll_one..poll_one..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute one ready handler.
+
+
+ count_type ``[link asio.reference.io_context.poll_one.overload1 poll_one]``();
+ `` [''''&raquo;''' [link asio.reference.io_context.poll_one.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute one ready handler.
+
+
+ count_type ``[link asio.reference.io_context.poll_one.overload2 poll_one]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.io_context.poll_one.overload2 more...]]``
+
+
+[section:overload1 io_context::poll_one (1 of 2 overloads)]
+
+
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute one ready handler.
+
+
+ count_type poll_one();
+
+
+The `poll_one()` function runs at most one handler that is ready to run, without blocking.
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::poll_one (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute one ready handler.
+
+
+ count_type poll_one(
+ asio::error_code & ec);
+
+
+The `poll_one()` function runs at most one handler that is ready to run, without blocking.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:post io_context::post]
+
+[indexterm2 asio.indexterm.io_context.post..post..io_context]
+(Deprecated: Use [link asio.reference.post `post`].) Request the [link asio.reference.io_context `io_context`] to invoke the given handler and return immediately.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` post(
+ CompletionHandler && handler);
+
+
+This function is used to ask the [link asio.reference.io_context `io_context`] to execute the given handler, but without allowing the [link asio.reference.io_context `io_context`] to call the handler from inside this function.
+
+The [link asio.reference.io_context `io_context`] guarantees that the handler will only be called in a thread in which the `run()`, `run_one()`, `poll()` or `poll_one()` member functions is currently being invoked.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called. The [link asio.reference.io_context `io_context`] will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler();
+``
+]]
+
+]
+
+
+[heading Remarks]
+
+This function throws an exception only if:
+
+
+* the handler's `asio_handler_allocate` function; or
+
+
+* the handler's copy constructor
+
+throws an exception.
+
+
+[endsect]
+
+
+
+[section:reset io_context::reset]
+
+[indexterm2 asio.indexterm.io_context.reset..reset..io_context]
+(Deprecated: Use `restart()`.) Reset the [link asio.reference.io_context `io_context`] in preparation for a subsequent `run()` invocation.
+
+
+ void reset();
+
+
+This function must be called prior to any second or later set of invocations of the `run()`, `run_one()`, `poll()` or `poll_one()` functions when a previous invocation of these functions returned due to the [link asio.reference.io_context `io_context`] being stopped or running out of work. After a call to `restart()`, the [link asio.reference.io_context `io_context`] object's `stopped()` function will return `false`.
+
+This function must not be called while there are any unfinished calls to the `run()`, `run_one()`, `poll()` or `poll_one()` functions.
+
+
+[endsect]
+
+
+
+[section:restart io_context::restart]
+
+[indexterm2 asio.indexterm.io_context.restart..restart..io_context]
+Restart the [link asio.reference.io_context `io_context`] in preparation for a subsequent `run()` invocation.
+
+
+ void restart();
+
+
+This function must be called prior to any second or later set of invocations of the `run()`, `run_one()`, `poll()` or `poll_one()` functions when a previous invocation of these functions returned due to the [link asio.reference.io_context `io_context`] being stopped or running out of work. After a call to `restart()`, the [link asio.reference.io_context `io_context`] object's `stopped()` function will return `false`.
+
+This function must not be called while there are any unfinished calls to the `run()`, `run_one()`, `poll()` or `poll_one()` functions.
+
+
+[endsect]
+
+
+[section:run io_context::run]
+
+[indexterm2 asio.indexterm.io_context.run..run..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop.
+
+
+ count_type ``[link asio.reference.io_context.run.overload1 run]``();
+ `` [''''&raquo;''' [link asio.reference.io_context.run.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop.
+
+
+ count_type ``[link asio.reference.io_context.run.overload2 run]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.io_context.run.overload2 more...]]``
+
+
+[section:overload1 io_context::run (1 of 2 overloads)]
+
+
+Run the [link asio.reference.io_context `io_context`] object's event processing loop.
+
+
+ count_type run();
+
+
+The `run()` function blocks until all work has finished and there are no more handlers to be dispatched, or until the [link asio.reference.io_context `io_context`] has been stopped.
+
+Multiple threads may call the `run()` function to set up a pool of threads from which the [link asio.reference.io_context `io_context`] may execute handlers. All threads that are waiting in the pool are equivalent and the [link asio.reference.io_context `io_context`] may choose any one of them to invoke a handler.
+
+A normal exit from the `run()` function implies that the [link asio.reference.io_context `io_context`] object is stopped (the `stopped()` function returns `true`). Subsequent calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately unless there is a prior call to `restart()`.
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+[heading Remarks]
+
+The `run()` function must not be called from a thread that is currently calling one of `run()`, `run_one()`, `poll()` or `poll_one()` on the same [link asio.reference.io_context `io_context`] object.
+
+The `poll()` function may also be used to dispatch ready handlers, but without blocking.
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::run (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overload.) Run the [link asio.reference.io_context `io_context`] object's event processing loop.
+
+
+ count_type run(
+ asio::error_code & ec);
+
+
+The `run()` function blocks until all work has finished and there are no more handlers to be dispatched, or until the [link asio.reference.io_context `io_context`] has been stopped.
+
+Multiple threads may call the `run()` function to set up a pool of threads from which the [link asio.reference.io_context `io_context`] may execute handlers. All threads that are waiting in the pool are equivalent and the [link asio.reference.io_context `io_context`] may choose any one of them to invoke a handler.
+
+A normal exit from the `run()` function implies that the [link asio.reference.io_context `io_context`] object is stopped (the `stopped()` function returns `true`). Subsequent calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately unless there is a prior call to `restart()`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+[heading Remarks]
+
+The `run()` function must not be called from a thread that is currently calling one of `run()`, `run_one()`, `poll()` or `poll_one()` on the same [link asio.reference.io_context `io_context`] object.
+
+The `poll()` function may also be used to dispatch ready handlers, but without blocking.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:run_for io_context::run_for]
+
+[indexterm2 asio.indexterm.io_context.run_for..run_for..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop for a specified duration.
+
+
+ template<
+ typename Rep,
+ typename Period>
+ std::size_t run_for(
+ const chrono::duration< Rep, Period > & rel_time);
+
+
+The `run_for()` function blocks until all work has finished and there are no more handlers to be dispatched, until the [link asio.reference.io_context `io_context`] has been stopped, or until the specified duration has elapsed.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[rel_time][The duration for which the call may block.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+[section:run_one io_context::run_one]
+
+[indexterm2 asio.indexterm.io_context.run_one..run_one..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute at most one handler.
+
+
+ count_type ``[link asio.reference.io_context.run_one.overload1 run_one]``();
+ `` [''''&raquo;''' [link asio.reference.io_context.run_one.overload1 more...]]``
+
+
+(Deprecated: Use non-error\_code overlaod.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute at most one handler.
+
+
+ count_type ``[link asio.reference.io_context.run_one.overload2 run_one]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.io_context.run_one.overload2 more...]]``
+
+
+[section:overload1 io_context::run_one (1 of 2 overloads)]
+
+
+Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute at most one handler.
+
+
+ count_type run_one();
+
+
+The `run_one()` function blocks until one handler has been dispatched, or until the [link asio.reference.io_context `io_context`] has been stopped.
+
+
+[heading Return Value]
+
+The number of handlers that were executed. A zero return value implies that the [link asio.reference.io_context `io_context`] object is stopped (the `stopped()` function returns `true`). Subsequent calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately unless there is a prior call to `restart()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::run_one (2 of 2 overloads)]
+
+
+(Deprecated: Use non-error\_code overlaod.) Run the [link asio.reference.io_context `io_context`] object's event processing loop to execute at most one handler.
+
+
+ count_type run_one(
+ asio::error_code & ec);
+
+
+The `run_one()` function blocks until one handler has been dispatched, or until the [link asio.reference.io_context `io_context`] has been stopped.
+
+
+[heading Return Value]
+
+The number of handlers that were executed. A zero return value implies that the [link asio.reference.io_context `io_context`] object is stopped (the `stopped()` function returns `true`). Subsequent calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately unless there is a prior call to `restart()`.
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:run_one_for io_context::run_one_for]
+
+[indexterm2 asio.indexterm.io_context.run_one_for..run_one_for..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop for a specified duration to execute at most one handler.
+
+
+ template<
+ typename Rep,
+ typename Period>
+ std::size_t run_one_for(
+ const chrono::duration< Rep, Period > & rel_time);
+
+
+The `run_one_for()` function blocks until one handler has been dispatched, until the [link asio.reference.io_context `io_context`] has been stopped, or until the specified duration has elapsed.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[rel_time][The duration for which the call may block.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+
+[section:run_one_until io_context::run_one_until]
+
+[indexterm2 asio.indexterm.io_context.run_one_until..run_one_until..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop until a specified time to execute at most one handler.
+
+
+ template<
+ typename Clock,
+ typename Duration>
+ std::size_t run_one_until(
+ const chrono::time_point< Clock, Duration > & abs_time);
+
+
+The `run_one_until()` function blocks until one handler has been dispatched, until the [link asio.reference.io_context `io_context`] has been stopped, or until the specified time has been reached.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[abs_time][The time point until which the call may block.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+
+[section:run_until io_context::run_until]
+
+[indexterm2 asio.indexterm.io_context.run_until..run_until..io_context]
+Run the [link asio.reference.io_context `io_context`] object's event processing loop until a specified time.
+
+
+ template<
+ typename Clock,
+ typename Duration>
+ std::size_t run_until(
+ const chrono::time_point< Clock, Duration > & abs_time);
+
+
+The `run_until()` function blocks until all work has finished and there are no more handlers to be dispatched, until the [link asio.reference.io_context `io_context`] has been stopped, or until the specified time has been reached.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[abs_time][The time point until which the call may block.]]
+
+]
+
+
+[heading Return Value]
+
+The number of handlers that were executed.
+
+
+
+
+[endsect]
+
+
+
+[section:shutdown io_context::shutdown]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.io_context.shutdown..shutdown..io_context]
+Shuts down all services in the context.
+
+
+ void shutdown();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order of the beginning of service object lifetime, performs `svc->shutdown()`.
+
+
+
+
+[endsect]
+
+
+
+[section:stop io_context::stop]
+
+[indexterm2 asio.indexterm.io_context.stop..stop..io_context]
+Stop the [link asio.reference.io_context `io_context`] object's event processing loop.
+
+
+ void stop();
+
+
+This function does not block, but instead simply signals the [link asio.reference.io_context `io_context`] to stop. All invocations of its `run()` or `run_one()` member functions should return as soon as possible. Subsequent calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately until `restart()` is called.
+
+
+[endsect]
+
+
+
+[section:stopped io_context::stopped]
+
+[indexterm2 asio.indexterm.io_context.stopped..stopped..io_context]
+Determine whether the [link asio.reference.io_context `io_context`] object has been stopped.
+
+
+ bool stopped() const;
+
+
+This function is used to determine whether an [link asio.reference.io_context `io_context`] object has been stopped, either through an explicit call to `stop()`, or due to running out of work. When an [link asio.reference.io_context `io_context`] object is stopped, calls to `run()`, `run_one()`, `poll()` or `poll_one()` will return immediately without invoking any handlers.
+
+
+[heading Return Value]
+
+`true` if the [link asio.reference.io_context `io_context`] object is stopped, otherwise `false`.
+
+
+
+
+[endsect]
+
+
+[section:use_service io_context::use_service]
+
+[indexterm2 asio.indexterm.io_context.use_service..use_service..io_context]
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.io_context.use_service.overload1 use_service]``(
+ io_context & ioc);
+ `` [''''&raquo;''' [link asio.reference.io_context.use_service.overload1 more...]]``
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.io_context.use_service.overload2 use_service]``(
+ execution_context & e);
+ `` [''''&raquo;''' [link asio.reference.io_context.use_service.overload2 more...]]``
+
+
+[section:overload1 io_context::use_service (1 of 2 overloads)]
+
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ io_context & ioc);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.io_context `io_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ioc][The [link asio.reference.io_context `io_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+[heading Remarks]
+
+This overload is preserved for backwards compatibility with services that inherit from [link asio.reference.io_context__service `io_context::service`].
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::use_service (2 of 2 overloads)]
+
+
+['Inherited from execution_context.]
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ execution_context & e);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.execution_context `execution_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wrap io_context::wrap]
+
+[indexterm2 asio.indexterm.io_context.wrap..wrap..io_context]
+(Deprecated: Use [link asio.reference.bind_executor `bind_executor`].) Create a new handler that automatically dispatches the wrapped handler on the [link asio.reference.io_context `io_context`].
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ unspecified wrap(
+ Handler handler);
+
+
+This function is used to create a new handler function object that, when invoked, will automatically pass the wrapped handler to the [link asio.reference.io_context `io_context`] object's dispatch function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be wrapped. The [link asio.reference.io_context `io_context`] will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler(A1 a1, ... An an);
+``
+]]
+
+]
+
+
+[heading Return Value]
+
+A function object that, when invoked, passes the wrapped handler to the [link asio.reference.io_context `io_context`] object's dispatch function. Given a function object with the signature:
+
+ R f(A1 a1, ... An an);
+
+
+If this function object is passed to the wrap function like so:
+
+ io_context.wrap(f);
+
+
+then the return value is a function object with the signature
+
+ void g(A1 a1, ... An an);
+
+
+that, when invoked, executes code equivalent to:
+
+ io_context.dispatch(boost::bind(f, a1, ... an));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:_io_context io_context::~io_context]
+
+[indexterm2 asio.indexterm.io_context._io_context..~io_context..io_context]
+Destructor.
+
+
+ ~io_context();
+
+
+On destruction, the [link asio.reference.io_context `io_context`] performs the following sequence of operations:
+
+
+* For each service object `svc` in the [link asio.reference.io_context `io_context`] set, in reverse order of the beginning of service object lifetime, performs `svc->shutdown()`.
+
+
+* Uninvoked handler objects that were scheduled for deferred invocation on the [link asio.reference.io_context `io_context`], or any associated strand, are destroyed.
+
+
+* For each service object `svc` in the [link asio.reference.io_context `io_context`] set, in reverse order of the beginning of service object lifetime, performs `delete static_cast<io_context::service*>(svc)`.
+
+
+[heading Remarks]
+
+The destruction sequence described above permits programs to simplify their resource management by using `shared_ptr<>`. Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), a `shared_ptr` to the object would be bound into the handlers for all asynchronous operations associated with it. This works as follows:
+
+
+* When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all `shared_ptr` references to the objects are destroyed.
+
+
+* To shut down the whole program, the [link asio.reference.io_context `io_context`] function `stop()` is called to terminate any `run()` calls as soon as possible. The [link asio.reference.io_context `io_context`] destructor defined above destroys all handlers, causing all `shared_ptr` references to all connection objects to be destroyed.
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:io_context__executor_type io_context::executor_type]
+
+
+Executor used to submit functions to an [link asio.reference.io_context `io_context`].
+
+
+ class executor_type
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context io_context::executor_type::context]
+
+[indexterm2 asio.indexterm.io_context__executor_type.context..context..io_context::executor_type]
+Obtain the underlying execution context.
+
+
+ io_context & context() const;
+
+
+
+[endsect]
+
+
+
+[section:defer io_context::executor_type::defer]
+
+[indexterm2 asio.indexterm.io_context__executor_type.defer..defer..io_context::executor_type]
+Request the [link asio.reference.io_context `io_context`] to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the [link asio.reference.io_context `io_context`] to execute the given function object. The function object will never be executed inside `defer()`. Instead, it will be scheduled to run on the [link asio.reference.io_context `io_context`].
+
+If the current thread belongs to the [link asio.reference.io_context `io_context`], `defer()` will delay scheduling the function object until the current thread returns control to the pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch io_context::executor_type::dispatch]
+
+[indexterm2 asio.indexterm.io_context__executor_type.dispatch..dispatch..io_context::executor_type]
+Request the [link asio.reference.io_context `io_context`] to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the [link asio.reference.io_context `io_context`] to execute the given function object. If the current thread is running the [link asio.reference.io_context `io_context`], `dispatch()` executes the function before returning. Otherwise, the function will be scheduled to run on the [link asio.reference.io_context `io_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:on_work_finished io_context::executor_type::on_work_finished]
+
+[indexterm2 asio.indexterm.io_context__executor_type.on_work_finished..on_work_finished..io_context::executor_type]
+Inform the [link asio.reference.io_context `io_context`] that some work is no longer outstanding.
+
+
+ void on_work_finished() const;
+
+
+This function is used to inform the [link asio.reference.io_context `io_context`] that some work has finished. Once the count of unfinished work reaches zero, the [link asio.reference.io_context `io_context`] is stopped and the `run()` and `run_one()` functions may exit.
+
+
+[endsect]
+
+
+
+[section:on_work_started io_context::executor_type::on_work_started]
+
+[indexterm2 asio.indexterm.io_context__executor_type.on_work_started..on_work_started..io_context::executor_type]
+Inform the [link asio.reference.io_context `io_context`] that it has some outstanding work to do.
+
+
+ void on_work_started() const;
+
+
+This function is used to inform the [link asio.reference.io_context `io_context`] that some work has begun. This ensures that the io\_context's `run()` and `run_one()` functions do not exit while the work is underway.
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ io_context::executor_type::operator!=]
+
+[indexterm2 asio.indexterm.io_context__executor_type.operator_not__eq_..operator!=..io_context::executor_type]
+Compare two executors for inequality.
+
+
+ friend bool operator!=(
+ const executor_type & a,
+ const executor_type & b);
+
+
+Two executors are equal if they refer to the same underlying [link asio.reference.io_context `io_context`].
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ io_context::executor_type::operator==]
+
+[indexterm2 asio.indexterm.io_context__executor_type.operator_eq__eq_..operator==..io_context::executor_type]
+Compare two executors for equality.
+
+
+ friend bool operator==(
+ const executor_type & a,
+ const executor_type & b);
+
+
+Two executors are equal if they refer to the same underlying [link asio.reference.io_context `io_context`].
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:post io_context::executor_type::post]
+
+[indexterm2 asio.indexterm.io_context__executor_type.post..post..io_context::executor_type]
+Request the [link asio.reference.io_context `io_context`] to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the [link asio.reference.io_context `io_context`] to execute the given function object. The function object will never be executed inside `post()`. Instead, it will be scheduled to run on the [link asio.reference.io_context `io_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:running_in_this_thread io_context::executor_type::running_in_this_thread]
+
+[indexterm2 asio.indexterm.io_context__executor_type.running_in_this_thread..running_in_this_thread..io_context::executor_type]
+Determine whether the [link asio.reference.io_context `io_context`] is running in the current thread.
+
+
+ bool running_in_this_thread() const;
+
+
+
+[heading Return Value]
+
+`true` if the current thread is running the [link asio.reference.io_context `io_context`]. Otherwise returns `false`.
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:io_context__service io_context::service]
+
+
+Base class for all [link asio.reference.io_context `io_context`] services.
+
+
+ class service
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__service.get_io_context [*get_io_context]]]
+ [Get the io_context object that owns the service. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__service.get_io_service [*get_io_service]]]
+ [Get the io_context object that owns the service. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__service.service [*service]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__service._service [*~service]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:get_io_context io_context::service::get_io_context]
+
+[indexterm2 asio.indexterm.io_context__service.get_io_context..get_io_context..io_context::service]
+Get the [link asio.reference.io_context `io_context`] object that owns the service.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service io_context::service::get_io_service]
+
+[indexterm2 asio.indexterm.io_context__service.get_io_service..get_io_service..io_context::service]
+Get the [link asio.reference.io_context `io_context`] object that owns the service.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+
+[section:service io_context::service::service]
+
+[indexterm2 asio.indexterm.io_context__service.service..service..io_context::service]
+Constructor.
+
+
+ service(
+ asio::io_context & owner);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[owner][The [link asio.reference.io_context `io_context`] object that owns the service. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:_service io_context::service::~service]
+
+[indexterm2 asio.indexterm.io_context__service._service..~service..io_context::service]
+Destructor.
+
+
+ virtual ~service();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:io_context__strand io_context::strand]
+
+
+Provides serialised handler execution.
+
+
+ class strand
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__strand.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.defer [*defer]]]
+ [Request the strand to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.dispatch [*dispatch]]]
+ [Request the strand to invoke the given function object.
+
+ (Deprecated: Use asio::dispatch().) Request the strand to invoke the given handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.get_io_context [*get_io_context]]]
+ [(Deprecated: Use context().) Get the io_context associated with the strand. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.get_io_service [*get_io_service]]]
+ [(Deprecated: Use context().) Get the io_context associated with the strand. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.on_work_finished [*on_work_finished]]]
+ [Inform the strand that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.on_work_started [*on_work_started]]]
+ [Inform the strand that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.post [*post]]]
+ [Request the strand to invoke the given function object.
+
+ (Deprecated: Use asio::post().) Request the strand to invoke the given handler and return immediately. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the strand is running in the current thread. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.strand [*strand]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.wrap [*wrap]]]
+ [(Deprecated: Use asio::bind_executor().) Create a new handler that automatically dispatches the wrapped handler on the strand. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand._strand [*~strand]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__strand.operator_not__eq_ [*operator!=]]]
+ [Compare two strands for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__strand.operator_eq__eq_ [*operator==]]]
+ [Compare two strands for equality. ]
+ ]
+
+]
+
+The [link asio.reference.io_context__strand `io_context::strand`] class provides the ability to post and dispatch handlers with the guarantee that none of those handlers will execute concurrently.
+
+
+[heading Order of handler invocation]
+
+Given:
+
+
+* a strand object `s`
+
+
+* an object `a` meeting completion handler requirements
+
+
+* an object `a1` which is an arbitrary copy of `a` made by the implementation
+
+
+* an object `b` meeting completion handler requirements
+
+
+* an object `b1` which is an arbitrary copy of `b` made by the implementation
+
+if any of the following conditions are true:
+
+
+* `s.post(a)` happens-before `s.post(b)`
+
+
+* `s.post(a)` happens-before `s.dispatch(b)`, where the latter is performed outside the strand
+
+
+* `s.dispatch(a)` happens-before `s.post(b)`, where the former is performed outside the strand
+
+
+* `s.dispatch(a)` happens-before `s.dispatch(b)`, where both are performed outside the strand
+
+then `asio_handler_invoke(a1, &a1)` happens-before `asio_handler_invoke(b1, &b1)`.
+
+Note that in the following case:
+
+ async_op_1(..., s.wrap(a));
+ async_op_2(..., s.wrap(b));
+
+
+the completion of the first async operation will perform `s.dispatch(a)`, and the second will perform `s.dispatch(b)`, but the order in which those are performed is unspecified. That is, you cannot state whether one happens-before the other. Therefore none of the above conditions are met and no ordering guarantee is made.
+
+
+[heading Remarks]
+
+The implementation makes no guarantee that handlers posted or dispatched through different `strand` objects will be invoked concurrently.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_context_strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context io_context::strand::context]
+
+[indexterm2 asio.indexterm.io_context__strand.context..context..io_context::strand]
+Obtain the underlying execution context.
+
+
+ asio::io_context & context();
+
+
+
+[endsect]
+
+
+
+[section:defer io_context::strand::defer]
+
+[indexterm2 asio.indexterm.io_context__strand.defer..defer..io_context::strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled to run by the underlying [link asio.reference.io_context `io_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:dispatch io_context::strand::dispatch]
+
+[indexterm2 asio.indexterm.io_context__strand.dispatch..dispatch..io_context::strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void ``[link asio.reference.io_context__strand.dispatch.overload1 dispatch]``(
+ Function && f,
+ const Allocator & a);
+ `` [''''&raquo;''' [link asio.reference.io_context__strand.dispatch.overload1 more...]]``
+
+
+(Deprecated: Use [link asio.reference.dispatch `dispatch`].) Request the strand to invoke the given handler.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.io_context__strand.dispatch.overload2 dispatch]``(
+ CompletionHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.io_context__strand.dispatch.overload2 more...]]``
+
+
+[section:overload1 io_context::strand::dispatch (1 of 2 overloads)]
+
+
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the strand to execute the given function object on its underlying [link asio.reference.io_context `io_context`]. The function object will be executed inside this function if the strand is not otherwise busy and if the underlying io\_context's executor's `dispatch()` function is also able to execute the function before returning.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::strand::dispatch (2 of 2 overloads)]
+
+
+(Deprecated: Use [link asio.reference.dispatch `dispatch`].) Request the strand to invoke the given handler.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` dispatch(
+ CompletionHandler && handler);
+
+
+This function is used to ask the strand to execute the given handler.
+
+The strand object guarantees that handlers posted or dispatched through the strand will not be executed concurrently. The handler may be executed inside this function if the guarantee can be met. If this function is called from within a handler that was posted or dispatched through the same strand, then the new handler will be executed immediately.
+
+The strand's guarantee is in addition to the guarantee provided by the underlying [link asio.reference.io_context `io_context`]. The [link asio.reference.io_context `io_context`] guarantees that the handler will only be called in a thread in which the io\_context's run member function is currently being invoked.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called. The strand will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler();
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:get_io_context io_context::strand::get_io_context]
+
+[indexterm2 asio.indexterm.io_context__strand.get_io_context..get_io_context..io_context::strand]
+(Deprecated: Use `context()`.) Get the [link asio.reference.io_context `io_context`] associated with the strand.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the strand uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the strand will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service io_context::strand::get_io_service]
+
+[indexterm2 asio.indexterm.io_context__strand.get_io_service..get_io_service..io_context::strand]
+(Deprecated: Use `context()`.) Get the [link asio.reference.io_context `io_context`] associated with the strand.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the strand uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the strand will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:on_work_finished io_context::strand::on_work_finished]
+
+[indexterm2 asio.indexterm.io_context__strand.on_work_finished..on_work_finished..io_context::strand]
+Inform the strand that some work is no longer outstanding.
+
+
+ void on_work_finished();
+
+
+The strand delegates this call to its underlying [link asio.reference.io_context `io_context`].
+
+
+[endsect]
+
+
+
+[section:on_work_started io_context::strand::on_work_started]
+
+[indexterm2 asio.indexterm.io_context__strand.on_work_started..on_work_started..io_context::strand]
+Inform the strand that it has some outstanding work to do.
+
+
+ void on_work_started();
+
+
+The strand delegates this call to its underlying [link asio.reference.io_context `io_context`].
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ io_context::strand::operator!=]
+
+[indexterm2 asio.indexterm.io_context__strand.operator_not__eq_..operator!=..io_context::strand]
+Compare two strands for inequality.
+
+
+ friend bool operator!=(
+ const strand & a,
+ const strand & b);
+
+
+Two strands are equal if they refer to the same ordered, non-concurrent state.
+
+[heading Requirements]
+
+['Header: ][^asio/io_context_strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ io_context::strand::operator==]
+
+[indexterm2 asio.indexterm.io_context__strand.operator_eq__eq_..operator==..io_context::strand]
+Compare two strands for equality.
+
+
+ friend bool operator==(
+ const strand & a,
+ const strand & b);
+
+
+Two strands are equal if they refer to the same ordered, non-concurrent state.
+
+[heading Requirements]
+
+['Header: ][^asio/io_context_strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:post io_context::strand::post]
+
+[indexterm2 asio.indexterm.io_context__strand.post..post..io_context::strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void ``[link asio.reference.io_context__strand.post.overload1 post]``(
+ Function && f,
+ const Allocator & a);
+ `` [''''&raquo;''' [link asio.reference.io_context__strand.post.overload1 more...]]``
+
+
+(Deprecated: Use [link asio.reference.post `post`].) Request the strand to invoke the given handler and return immediately.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.io_context__strand.post.overload2 post]``(
+ CompletionHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.io_context__strand.post.overload2 more...]]``
+
+
+[section:overload1 io_context::strand::post (1 of 2 overloads)]
+
+
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled to run by the underlying [link asio.reference.io_context `io_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::strand::post (2 of 2 overloads)]
+
+
+(Deprecated: Use [link asio.reference.post `post`].) Request the strand to invoke the given handler and return immediately.
+
+
+ template<
+ typename ``[link asio.reference.CompletionHandler CompletionHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` post(
+ CompletionHandler && handler);
+
+
+This function is used to ask the strand to execute the given handler, but without allowing the strand to call the handler from inside this function.
+
+The strand object guarantees that handlers posted or dispatched through the strand will not be executed concurrently. The strand's guarantee is in addition to the guarantee provided by the underlying [link asio.reference.io_context `io_context`]. The [link asio.reference.io_context `io_context`] guarantees that the handler will only be called in a thread in which the io\_context's run member function is currently being invoked.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called. The strand will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler();
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:running_in_this_thread io_context::strand::running_in_this_thread]
+
+[indexterm2 asio.indexterm.io_context__strand.running_in_this_thread..running_in_this_thread..io_context::strand]
+Determine whether the strand is running in the current thread.
+
+
+ bool running_in_this_thread() const;
+
+
+
+[heading Return Value]
+
+`true` if the current thread is executing a handler that was submitted to the strand using `post()`, `dispatch()` or `wrap()`. Otherwise returns `false`.
+
+
+
+
+[endsect]
+
+
+
+[section:strand io_context::strand::strand]
+
+[indexterm2 asio.indexterm.io_context__strand.strand..strand..io_context::strand]
+Constructor.
+
+
+ strand(
+ asio::io_context & io_context);
+
+
+Constructs the strand.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the strand will use to dispatch handlers that are ready to be run. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:wrap io_context::strand::wrap]
+
+[indexterm2 asio.indexterm.io_context__strand.wrap..wrap..io_context::strand]
+(Deprecated: Use [link asio.reference.bind_executor `bind_executor`].) Create a new handler that automatically dispatches the wrapped handler on the strand.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ unspecified wrap(
+ Handler handler);
+
+
+This function is used to create a new handler function object that, when invoked, will automatically pass the wrapped handler to the strand's dispatch function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be wrapped. The strand will make a copy of the handler object as required. The function signature of the handler must be:
+``
+ void handler(A1 a1, ... An an);
+``
+]]
+
+]
+
+
+[heading Return Value]
+
+A function object that, when invoked, passes the wrapped handler to the strand's dispatch function. Given a function object with the signature:
+
+ R f(A1 a1, ... An an);
+
+
+If this function object is passed to the wrap function like so:
+
+ strand.wrap(f);
+
+
+then the return value is a function object with the signature
+
+ void g(A1 a1, ... An an);
+
+
+that, when invoked, executes code equivalent to:
+
+ strand.dispatch(boost::bind(f, a1, ... an));
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:_strand io_context::strand::~strand]
+
+[indexterm2 asio.indexterm.io_context__strand._strand..~strand..io_context::strand]
+Destructor.
+
+
+ ~strand();
+
+
+Destroys a strand.
+
+Handlers posted through the strand that have not yet been invoked will still be dispatched in a way that meets the guarantee of non-concurrency.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:io_context__work io_context::work]
+
+
+(Deprecated: Use [link asio.reference.executor_work_guard `executor_work_guard`].) Class to inform the [link asio.reference.io_context `io_context`] when it has work to do.
+
+
+ class work
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__work.get_io_context [*get_io_context]]]
+ [Get the io_context associated with the work. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__work.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_io_context().) Get the io_context associated with the work. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__work.work [*work]]]
+ [Constructor notifies the io_context that work is starting.
+
+ Copy constructor notifies the io_context that work is starting. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__work._work [*~work]]]
+ [Destructor notifies the io_context that the work is complete. ]
+ ]
+
+]
+
+The work class is used to inform the [link asio.reference.io_context `io_context`] when work starts and finishes. This ensures that the [link asio.reference.io_context `io_context`] object's `run()` function will not exit while work is underway, and that it does exit when there is no unfinished work remaining.
+
+The work class is copy-constructible so that it may be used as a data member in a handler class. It is not assignable.
+
+[heading Requirements]
+
+['Header: ][^asio/io_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:get_io_context io_context::work::get_io_context]
+
+[indexterm2 asio.indexterm.io_context__work.get_io_context..get_io_context..io_context::work]
+Get the [link asio.reference.io_context `io_context`] associated with the work.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service io_context::work::get_io_service]
+
+[indexterm2 asio.indexterm.io_context__work.get_io_service..get_io_service..io_context::work]
+(Deprecated: Use `get_io_context()`.) Get the [link asio.reference.io_context `io_context`] associated with the work.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+[section:work io_context::work::work]
+
+[indexterm2 asio.indexterm.io_context__work.work..work..io_context::work]
+Constructor notifies the [link asio.reference.io_context `io_context`] that work is starting.
+
+
+ explicit ``[link asio.reference.io_context__work.work.overload1 work]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.io_context__work.work.overload1 more...]]``
+
+
+Copy constructor notifies the [link asio.reference.io_context `io_context`] that work is starting.
+
+
+ ``[link asio.reference.io_context__work.work.overload2 work]``(
+ const work & other);
+ `` [''''&raquo;''' [link asio.reference.io_context__work.work.overload2 more...]]``
+
+
+[section:overload1 io_context::work::work (1 of 2 overloads)]
+
+
+Constructor notifies the [link asio.reference.io_context `io_context`] that work is starting.
+
+
+ work(
+ asio::io_context & io_context);
+
+
+The constructor is used to inform the [link asio.reference.io_context `io_context`] that some work has begun. This ensures that the [link asio.reference.io_context `io_context`] object's `run()` function will not exit while the work is underway.
+
+
+[endsect]
+
+
+
+[section:overload2 io_context::work::work (2 of 2 overloads)]
+
+
+Copy constructor notifies the [link asio.reference.io_context `io_context`] that work is starting.
+
+
+ work(
+ const work & other);
+
+
+The constructor is used to inform the [link asio.reference.io_context `io_context`] that some work has begun. This ensures that the [link asio.reference.io_context `io_context`] object's `run()` function will not exit while the work is underway.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_work io_context::work::~work]
+
+[indexterm2 asio.indexterm.io_context__work._work..~work..io_context::work]
+Destructor notifies the [link asio.reference.io_context `io_context`] that the work is complete.
+
+
+ ~work();
+
+
+The destructor is used to inform the [link asio.reference.io_context `io_context`] that some work has finished. Once the count of unfinished work reaches zero, the [link asio.reference.io_context `io_context`] object's `run()` function is permitted to exit.
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:io_service io_service]
+
+[indexterm1 asio.indexterm.io_service..io_service]
+Typedef for backwards compatibility.
+
+
+ typedef io_context io_service;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.io_context__executor_type [*executor_type]]]
+ [Executor used to submit functions to an io_context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__service [*service]]]
+ [Base class for all io_context services. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__strand [*strand]]]
+ [Provides serialised handler execution. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context__work [*work]]]
+ [(Deprecated: Use executor_work_guard.) Class to inform the io_context when it has work to do. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context.count_type [*count_type]]]
+ [The type used to count the number of handlers executed by the context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.io_context.fork_event [*fork_event]]]
+ [Fork-related event notifications. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.dispatch [*dispatch]]]
+ [(Deprecated: Use asio::dispatch().) Request the io_context to invoke the given handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.get_executor [*get_executor]]]
+ [Obtains the executor associated with the io_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.io_context [*io_context]]]
+ [Constructor. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.notify_fork [*notify_fork]]]
+ [Notify the execution_context of a fork-related event. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.poll [*poll]]]
+ [Run the io_context object's event processing loop to execute ready handlers.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop to execute ready handlers. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.poll_one [*poll_one]]]
+ [Run the io_context object's event processing loop to execute one ready handler.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop to execute one ready handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.post [*post]]]
+ [(Deprecated: Use asio::post().) Request the io_context to invoke the given handler and return immediately. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.reset [*reset]]]
+ [(Deprecated: Use restart().) Reset the io_context in preparation for a subsequent run() invocation. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.restart [*restart]]]
+ [Restart the io_context in preparation for a subsequent run() invocation. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run [*run]]]
+ [Run the io_context object's event processing loop.
+
+ (Deprecated: Use non-error_code overload.) Run the io_context object's event processing loop. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_for [*run_for]]]
+ [Run the io_context object's event processing loop for a specified duration. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one [*run_one]]]
+ [Run the io_context object's event processing loop to execute at most one handler.
+
+ (Deprecated: Use non-error_code overlaod.) Run the io_context object's event processing loop to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one_for [*run_one_for]]]
+ [Run the io_context object's event processing loop for a specified duration to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_one_until [*run_one_until]]]
+ [Run the io_context object's event processing loop until a specified time to execute at most one handler. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.run_until [*run_until]]]
+ [Run the io_context object's event processing loop until a specified time. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.stop [*stop]]]
+ [Stop the io_context object's event processing loop. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.stopped [*stopped]]]
+ [Determine whether the io_context object has been stopped. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.wrap [*wrap]]]
+ [(Deprecated: Use asio::bind_executor().) Create a new handler that automatically dispatches the wrapped handler on the io_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context._io_context [*~io_context]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.destroy [*destroy]]]
+ [Destroys all services in the context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.shutdown [*shutdown]]]
+ [Shuts down all services in the context. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context.add_service [*add_service]]]
+ [(Deprecated: Use make_service().) Add a service object to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.has_service [*has_service]]]
+ [Determine if an execution_context contains a specified service type. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.make_service [*make_service]]]
+ [Creates a service object and adds it to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context.use_service [*use_service]]]
+ [
+
+ Obtain the service object corresponding to the given type. ]
+ ]
+
+]
+
+The [link asio.reference.io_context `io_context`] class provides the core I/O functionality for users of the asynchronous I/O objects, including:
+
+
+* `asio::ip::tcp::socket`
+
+* `asio::ip::tcp::acceptor`
+
+* `asio::ip::udp::socket`
+
+* [link asio.reference.deadline_timer `deadline_timer`].
+
+The [link asio.reference.io_context `io_context`] class also includes facilities intended for developers of custom asynchronous services.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe, with the specific exceptions of the `restart()` and `notify_fork()` functions. Calling `restart()` while there are unfinished `run()`, `run_one()`, `poll()` or `poll_one()` calls results in undefined behaviour. The `notify_fork()` function should not be called while any [link asio.reference.io_context `io_context`] function, or any function on an I/O object that is associated with the [link asio.reference.io_context `io_context`], is being called in another thread.
+
+
+
+[heading Synchronous and asynchronous operations]
+
+
+
+Synchronous operations on I/O objects implicitly run the [link asio.reference.io_context `io_context`] object for an individual operation. The [link asio.reference.io_context `io_context`] functions `run()`, `run_one()`, `poll()` or `poll_one()` must be called for the [link asio.reference.io_context `io_context`] to perform asynchronous operations on behalf of a C++ program. Notification that an asynchronous operation has completed is delivered by invocation of the associated handler. Handlers are invoked only by a thread that is currently calling any overload of `run()`, `run_one()`, `poll()` or `poll_one()` for the [link asio.reference.io_context `io_context`].
+
+
+[heading Effect of exceptions thrown from handlers]
+
+
+
+If an exception is thrown from a handler, the exception is allowed to propagate through the throwing thread's invocation of `run()`, `run_one()`, `poll()` or `poll_one()`. No other threads that are calling any of these functions are affected. It is then the responsibility of the application to catch the exception.
+
+After the exception has been caught, the `run()`, `run_one()`, `poll()` or `poll_one()` call may be restarted ['without] the need for an intervening call to `restart()`. This allows the thread to rejoin the [link asio.reference.io_context `io_context`] object's thread pool without impacting any other threads in the pool.
+
+For example:
+
+
+
+ asio::io_context io_context;
+ ...
+ for (;;)
+ {
+ try
+ {
+ io_context.run();
+ break; // run() exited normally
+ }
+ catch (my_exception& e)
+ {
+ // Deal with exception as appropriate.
+ }
+ }
+
+
+
+
+
+[heading Stopping the io_context from running out of work]
+
+
+
+Some applications may need to prevent an [link asio.reference.io_context `io_context`] object's `run()` call from returning when there is no more work to do. For example, the [link asio.reference.io_context `io_context`] may be being run in a background thread that is launched prior to the application's asynchronous operations. The `run()` call may be kept running by creating an object of type asio::executor\_work\_guard<io\_context::executor\_type>:
+
+
+
+ asio::io_context io_context;
+ asio::executor_work_guard<asio::io_context::executor_type>
+ = asio::make_work_guard(io_context);
+ ...
+
+
+
+
+To effect a shutdown, the application will then need to call the [link asio.reference.io_context `io_context`] object's `stop()` member function. This will cause the [link asio.reference.io_context `io_context`] `run()` call to return as soon as possible, abandoning unfinished operations and without permitting ready handlers to be dispatched.
+
+Alternatively, if the application requires that all operations and handlers be allowed to finish normally, the work object may be explicitly reset.
+
+
+
+ asio::io_context io_context;
+ asio::executor_work_guard<asio::io_context::executor_type>
+ = asio::make_work_guard(io_context);
+ ...
+ work.reset(); // Allow run() to exit.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/io_service.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:ip__address ip::address]
+
+
+Implements version-independent IP addresses.
+
+
+ class address
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address.address [*address]]]
+ [Default constructor.
+
+ Construct an address from an IPv4 address.
+
+ Construct an address from an IPv6 address.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.from_string [*from_string]]]
+ [(Deprecated: Use make_address().) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.is_v4 [*is_v4]]]
+ [Get whether the address is an IP version 4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.is_v6 [*is_v6]]]
+ [Get whether the address is an IP version 6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_eq_ [*operator=]]]
+ [Assign from another address.
+
+ Assign from an IPv4 address.
+
+ Assign from an IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.to_v4 [*to_v4]]]
+ [Get the address as an IP version 4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.to_v6 [*to_v6]]]
+ [Get the address as an IP version 6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address.make_address [*make_address]]]
+ [Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address `ip::address`] class provides the ability to use either IP version 4 or version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:address ip::address::address]
+
+[indexterm2 asio.indexterm.ip__address.address..address..ip::address]
+Default constructor.
+
+
+ ``[link asio.reference.ip__address.address.overload1 address]``();
+ `` [''''&raquo;''' [link asio.reference.ip__address.address.overload1 more...]]``
+
+
+Construct an address from an IPv4 address.
+
+
+ ``[link asio.reference.ip__address.address.overload2 address]``(
+ const asio::ip::address_v4 & ipv4_address);
+ `` [''''&raquo;''' [link asio.reference.ip__address.address.overload2 more...]]``
+
+
+Construct an address from an IPv6 address.
+
+
+ ``[link asio.reference.ip__address.address.overload3 address]``(
+ const asio::ip::address_v6 & ipv6_address);
+ `` [''''&raquo;''' [link asio.reference.ip__address.address.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__address.address.overload4 address]``(
+ const address & other);
+ `` [''''&raquo;''' [link asio.reference.ip__address.address.overload4 more...]]``
+
+
+[section:overload1 ip::address::address (1 of 4 overloads)]
+
+
+Default constructor.
+
+
+ address();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address::address (2 of 4 overloads)]
+
+
+Construct an address from an IPv4 address.
+
+
+ address(
+ const asio::ip::address_v4 & ipv4_address);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address::address (3 of 4 overloads)]
+
+
+Construct an address from an IPv6 address.
+
+
+ address(
+ const asio::ip::address_v6 & ipv6_address);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address::address (4 of 4 overloads)]
+
+
+Copy constructor.
+
+
+ address(
+ const address & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:from_string ip::address::from_string]
+
+[indexterm2 asio.indexterm.ip__address.from_string..from_string..ip::address]
+(Deprecated: Use `make_address()`.) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ static address ``[link asio.reference.ip__address.from_string.overload1 from_string]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address.from_string.overload1 more...]]``
+
+ static address ``[link asio.reference.ip__address.from_string.overload2 from_string]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address.from_string.overload2 more...]]``
+
+ static address ``[link asio.reference.ip__address.from_string.overload3 from_string]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address.from_string.overload3 more...]]``
+
+ static address ``[link asio.reference.ip__address.from_string.overload4 from_string]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address.from_string.overload4 more...]]``
+
+
+[section:overload1 ip::address::from_string (1 of 4 overloads)]
+
+
+(Deprecated: Use `make_address()`.) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ static address from_string(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address::from_string (2 of 4 overloads)]
+
+
+(Deprecated: Use `make_address()`.) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ static address from_string(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address::from_string (3 of 4 overloads)]
+
+
+(Deprecated: Use `make_address()`.) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ static address from_string(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address::from_string (4 of 4 overloads)]
+
+
+(Deprecated: Use `make_address()`.) Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ static address from_string(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_loopback ip::address::is_loopback]
+
+[indexterm2 asio.indexterm.ip__address.is_loopback..is_loopback..ip::address]
+Determine whether the address is a loopback address.
+
+
+ bool is_loopback() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast ip::address::is_multicast]
+
+[indexterm2 asio.indexterm.ip__address.is_multicast..is_multicast..ip::address]
+Determine whether the address is a multicast address.
+
+
+ bool is_multicast() const;
+
+
+
+[endsect]
+
+
+
+[section:is_unspecified ip::address::is_unspecified]
+
+[indexterm2 asio.indexterm.ip__address.is_unspecified..is_unspecified..ip::address]
+Determine whether the address is unspecified.
+
+
+ bool is_unspecified() const;
+
+
+
+[endsect]
+
+
+
+[section:is_v4 ip::address::is_v4]
+
+[indexterm2 asio.indexterm.ip__address.is_v4..is_v4..ip::address]
+Get whether the address is an IP version 4 address.
+
+
+ bool is_v4() const;
+
+
+
+[endsect]
+
+
+
+[section:is_v6 ip::address::is_v6]
+
+[indexterm2 asio.indexterm.ip__address.is_v6..is_v6..ip::address]
+Get whether the address is an IP version 6 address.
+
+
+ bool is_v6() const;
+
+
+
+[endsect]
+
+
+[section:make_address ip::address::make_address]
+
+[indexterm2 asio.indexterm.ip__address.make_address..make_address..ip::address]
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address ``[link asio.reference.ip__address.make_address.overload1 make_address]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload1 more...]]``
+
+ address ``[link asio.reference.ip__address.make_address.overload2 make_address]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload2 more...]]``
+
+ address ``[link asio.reference.ip__address.make_address.overload3 make_address]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload3 more...]]``
+
+ address ``[link asio.reference.ip__address.make_address.overload4 make_address]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload4 more...]]``
+
+ address ``[link asio.reference.ip__address.make_address.overload5 make_address]``(
+ string_view str);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload5 more...]]``
+
+ address ``[link asio.reference.ip__address.make_address.overload6 make_address]``(
+ string_view str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address.make_address.overload6 more...]]``
+
+
+[section:overload1 ip::address::make_address (1 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address::make_address (2 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address::make_address (3 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address::make_address (4 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::address::make_address (5 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ string_view str);
+
+
+
+[endsect]
+
+
+
+[section:overload6 ip::address::make_address (6 of 6 overloads)]
+
+
+Create an address from an IPv4 address string in dotted decimal form, or from an IPv6 address in hexadecimal notation.
+
+
+ address make_address(
+ string_view str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_not__eq_ ip::address::operator!=]
+
+[indexterm2 asio.indexterm.ip__address.operator_not__eq_..operator!=..ip::address]
+Compare two addresses for inequality.
+
+
+ friend bool operator!=(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ ip::address::operator<]
+
+[indexterm2 asio.indexterm.ip__address.operator_lt_..operator<..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator<(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt__lt_ ip::address::operator<<]
+
+[indexterm2 asio.indexterm.ip__address.operator_lt__lt_..operator<<..ip::address]
+Output an address as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const address & addr);
+
+
+Used to output a human-readable string for a specified address.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[addr][The address to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_lt__eq_ ip::address::operator<=]
+
+[indexterm2 asio.indexterm.ip__address.operator_lt__eq_..operator<=..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator<=(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_eq_ ip::address::operator=]
+
+[indexterm2 asio.indexterm.ip__address.operator_eq_..operator=..ip::address]
+Assign from another address.
+
+
+ address & ``[link asio.reference.ip__address.operator_eq_.overload1 operator=]``(
+ const address & other);
+ `` [''''&raquo;''' [link asio.reference.ip__address.operator_eq_.overload1 more...]]``
+
+
+Assign from an IPv4 address.
+
+
+ address & ``[link asio.reference.ip__address.operator_eq_.overload2 operator=]``(
+ const asio::ip::address_v4 & ipv4_address);
+ `` [''''&raquo;''' [link asio.reference.ip__address.operator_eq_.overload2 more...]]``
+
+
+Assign from an IPv6 address.
+
+
+ address & ``[link asio.reference.ip__address.operator_eq_.overload3 operator=]``(
+ const asio::ip::address_v6 & ipv6_address);
+ `` [''''&raquo;''' [link asio.reference.ip__address.operator_eq_.overload3 more...]]``
+
+
+[section:overload1 ip::address::operator= (1 of 3 overloads)]
+
+
+Assign from another address.
+
+
+ address & operator=(
+ const address & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address::operator= (2 of 3 overloads)]
+
+
+Assign from an IPv4 address.
+
+
+ address & operator=(
+ const asio::ip::address_v4 & ipv4_address);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address::operator= (3 of 3 overloads)]
+
+
+Assign from an IPv6 address.
+
+
+ address & operator=(
+ const asio::ip::address_v6 & ipv6_address);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq__eq_ ip::address::operator==]
+
+[indexterm2 asio.indexterm.ip__address.operator_eq__eq_..operator==..ip::address]
+Compare two addresses for equality.
+
+
+ friend bool operator==(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ ip::address::operator>]
+
+[indexterm2 asio.indexterm.ip__address.operator_gt_..operator>..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator>(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::address::operator>=]
+
+[indexterm2 asio.indexterm.ip__address.operator_gt__eq_..operator>=..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator>=(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:to_string ip::address::to_string]
+
+[indexterm2 asio.indexterm.ip__address.to_string..to_string..ip::address]
+Get the address as a string.
+
+
+ std::string ``[link asio.reference.ip__address.to_string.overload1 to_string]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__address.to_string.overload1 more...]]``
+
+
+(Deprecated: Use other overload.) Get the address as a string.
+
+
+ std::string ``[link asio.reference.ip__address.to_string.overload2 to_string]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.ip__address.to_string.overload2 more...]]``
+
+
+[section:overload1 ip::address::to_string (1 of 2 overloads)]
+
+
+Get the address as a string.
+
+
+ std::string to_string() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address::to_string (2 of 2 overloads)]
+
+
+(Deprecated: Use other overload.) Get the address as a string.
+
+
+ std::string to_string(
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:to_v4 ip::address::to_v4]
+
+[indexterm2 asio.indexterm.ip__address.to_v4..to_v4..ip::address]
+Get the address as an IP version 4 address.
+
+
+ asio::ip::address_v4 to_v4() const;
+
+
+
+[endsect]
+
+
+
+[section:to_v6 ip::address::to_v6]
+
+[indexterm2 asio.indexterm.ip__address.to_v6..to_v6..ip::address]
+Get the address as an IP version 6 address.
+
+
+ asio::ip::address_v6 to_v6() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__address_v4 ip::address_v4]
+
+
+Implements IP version 4 style addresses.
+
+
+ class address_v4
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:address_v4 ip::address_v4::address_v4]
+
+[indexterm2 asio.indexterm.ip__address_v4.address_v4..address_v4..ip::address_v4]
+Default constructor.
+
+
+ ``[link asio.reference.ip__address_v4.address_v4.overload1 address_v4]``();
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.address_v4.overload1 more...]]``
+
+
+Construct an address from raw bytes.
+
+
+ explicit ``[link asio.reference.ip__address_v4.address_v4.overload2 address_v4]``(
+ const bytes_type & bytes);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.address_v4.overload2 more...]]``
+
+
+Construct an address from an unsigned integer in host byte order.
+
+
+ explicit ``[link asio.reference.ip__address_v4.address_v4.overload3 address_v4]``(
+ uint_type addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.address_v4.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__address_v4.address_v4.overload4 address_v4]``(
+ const address_v4 & other);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.address_v4.overload4 more...]]``
+
+
+[section:overload1 ip::address_v4::address_v4 (1 of 4 overloads)]
+
+
+Default constructor.
+
+
+ address_v4();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::address_v4 (2 of 4 overloads)]
+
+
+Construct an address from raw bytes.
+
+
+ address_v4(
+ const bytes_type & bytes);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v4::address_v4 (3 of 4 overloads)]
+
+
+Construct an address from an unsigned integer in host byte order.
+
+
+ address_v4(
+ uint_type addr);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address_v4::address_v4 (4 of 4 overloads)]
+
+
+Copy constructor.
+
+
+ address_v4(
+ const address_v4 & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:any ip::address_v4::any]
+
+[indexterm2 asio.indexterm.ip__address_v4.any..any..ip::address_v4]
+Obtain an address object that represents any address.
+
+
+ static address_v4 any();
+
+
+
+[endsect]
+
+
+[section:broadcast ip::address_v4::broadcast]
+
+[indexterm2 asio.indexterm.ip__address_v4.broadcast..broadcast..ip::address_v4]
+Obtain an address object that represents the broadcast address.
+
+
+ static address_v4 ``[link asio.reference.ip__address_v4.broadcast.overload1 broadcast]``();
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.broadcast.overload1 more...]]``
+
+
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask.
+
+
+ static address_v4 ``[link asio.reference.ip__address_v4.broadcast.overload2 broadcast]``(
+ const address_v4 & addr,
+ const address_v4 & mask);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.broadcast.overload2 more...]]``
+
+
+[section:overload1 ip::address_v4::broadcast (1 of 2 overloads)]
+
+
+Obtain an address object that represents the broadcast address.
+
+
+ static address_v4 broadcast();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::broadcast (2 of 2 overloads)]
+
+
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask.
+
+
+ static address_v4 broadcast(
+ const address_v4 & addr,
+ const address_v4 & mask);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:bytes_type ip::address_v4::bytes_type]
+
+[indexterm2 asio.indexterm.ip__address_v4.bytes_type..bytes_type..ip::address_v4]
+The type used to represent an address as an array of bytes.
+
+
+ typedef array< unsigned char, 4 > bytes_type;
+
+
+
+
+[heading Remarks]
+
+This type is defined in terms of the C++0x template `std::array` when it is available. Otherwise, it uses `boost:array`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:from_string ip::address_v4::from_string]
+
+[indexterm2 asio.indexterm.ip__address_v4.from_string..from_string..ip::address_v4]
+(Deprecated: Use `make_address_v4()`.) Create an address from an IP address string in dotted decimal form.
+
+
+ static address_v4 ``[link asio.reference.ip__address_v4.from_string.overload1 from_string]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.from_string.overload1 more...]]``
+
+ static address_v4 ``[link asio.reference.ip__address_v4.from_string.overload2 from_string]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.from_string.overload2 more...]]``
+
+ static address_v4 ``[link asio.reference.ip__address_v4.from_string.overload3 from_string]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.from_string.overload3 more...]]``
+
+ static address_v4 ``[link asio.reference.ip__address_v4.from_string.overload4 from_string]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.from_string.overload4 more...]]``
+
+
+[section:overload1 ip::address_v4::from_string (1 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v4()`.) Create an address from an IP address string in dotted decimal form.
+
+
+ static address_v4 from_string(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::from_string (2 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v4()`.) Create an address from an IP address string in dotted decimal form.
+
+
+ static address_v4 from_string(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v4::from_string (3 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v4()`.) Create an address from an IP address string in dotted decimal form.
+
+
+ static address_v4 from_string(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address_v4::from_string (4 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v4()`.) Create an address from an IP address string in dotted decimal form.
+
+
+ static address_v4 from_string(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_class_a ip::address_v4::is_class_a]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_class_a..is_class_a..ip::address_v4]
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Determine whether the address is a class A address.
+
+
+ bool is_class_a() const;
+
+
+
+[endsect]
+
+
+
+[section:is_class_b ip::address_v4::is_class_b]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_class_b..is_class_b..ip::address_v4]
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Determine whether the address is a class B address.
+
+
+ bool is_class_b() const;
+
+
+
+[endsect]
+
+
+
+[section:is_class_c ip::address_v4::is_class_c]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_class_c..is_class_c..ip::address_v4]
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Determine whether the address is a class C address.
+
+
+ bool is_class_c() const;
+
+
+
+[endsect]
+
+
+
+[section:is_loopback ip::address_v4::is_loopback]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_loopback..is_loopback..ip::address_v4]
+Determine whether the address is a loopback address.
+
+
+ bool is_loopback() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast ip::address_v4::is_multicast]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_multicast..is_multicast..ip::address_v4]
+Determine whether the address is a multicast address.
+
+
+ bool is_multicast() const;
+
+
+
+[endsect]
+
+
+
+[section:is_unspecified ip::address_v4::is_unspecified]
+
+[indexterm2 asio.indexterm.ip__address_v4.is_unspecified..is_unspecified..ip::address_v4]
+Determine whether the address is unspecified.
+
+
+ bool is_unspecified() const;
+
+
+
+[endsect]
+
+
+
+[section:loopback ip::address_v4::loopback]
+
+[indexterm2 asio.indexterm.ip__address_v4.loopback..loopback..ip::address_v4]
+Obtain an address object that represents the loopback address.
+
+
+ static address_v4 loopback();
+
+
+
+[endsect]
+
+
+[section:make_address_v4 ip::address_v4::make_address_v4]
+
+[indexterm2 asio.indexterm.ip__address_v4.make_address_v4..make_address_v4..ip::address_v4]
+Create an IPv4 address from raw bytes in network order.
+
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload1 make_address_v4]``(
+ const address_v4::bytes_type & bytes);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload1 more...]]``
+
+
+Create an IPv4 address from an unsigned integer in host byte order.
+
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload2 make_address_v4]``(
+ address_v4::uint_type addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload2 more...]]``
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload3 make_address_v4]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload3 more...]]``
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload4 make_address_v4]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload4 more...]]``
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload5 make_address_v4]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload5 more...]]``
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload6 make_address_v4]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload6 more...]]``
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload7 make_address_v4]``(
+ string_view str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload7 more...]]``
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload8 make_address_v4]``(
+ string_view str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload8 more...]]``
+
+
+Create an IPv4 address from a IPv4-mapped IPv6 address.
+
+
+ address_v4 ``[link asio.reference.ip__address_v4.make_address_v4.overload9 make_address_v4]``(
+ v4_mapped_t ,
+ const address_v6 & v6_addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_address_v4.overload9 more...]]``
+
+
+[section:overload1 ip::address_v4::make_address_v4 (1 of 9 overloads)]
+
+
+Create an IPv4 address from raw bytes in network order.
+
+
+ address_v4 make_address_v4(
+ const address_v4::bytes_type & bytes);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::make_address_v4 (2 of 9 overloads)]
+
+
+Create an IPv4 address from an unsigned integer in host byte order.
+
+
+ address_v4 make_address_v4(
+ address_v4::uint_type addr);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v4::make_address_v4 (3 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address_v4::make_address_v4 (4 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::address_v4::make_address_v4 (5 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload6 ip::address_v4::make_address_v4 (6 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload7 ip::address_v4::make_address_v4 (7 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ string_view str);
+
+
+
+[endsect]
+
+
+
+[section:overload8 ip::address_v4::make_address_v4 (8 of 9 overloads)]
+
+
+Create an IPv4 address from an IP address string in dotted decimal form.
+
+
+ address_v4 make_address_v4(
+ string_view str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload9 ip::address_v4::make_address_v4 (9 of 9 overloads)]
+
+
+Create an IPv4 address from a IPv4-mapped IPv6 address.
+
+
+ address_v4 make_address_v4(
+ v4_mapped_t ,
+ const address_v6 & v6_addr);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:make_network_v4 ip::address_v4::make_network_v4]
+
+[indexterm2 asio.indexterm.ip__address_v4.make_network_v4..make_network_v4..ip::address_v4]
+Create an IPv4 network from an address and prefix length.
+
+
+ network_v4 ``[link asio.reference.ip__address_v4.make_network_v4.overload1 make_network_v4]``(
+ const address_v4 & addr,
+ unsigned short prefix_len);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_network_v4.overload1 more...]]``
+
+
+Create an IPv4 network from an address and netmask.
+
+
+ network_v4 ``[link asio.reference.ip__address_v4.make_network_v4.overload2 make_network_v4]``(
+ const address_v4 & addr,
+ const address_v4 & mask);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.make_network_v4.overload2 more...]]``
+
+
+[section:overload1 ip::address_v4::make_network_v4 (1 of 2 overloads)]
+
+
+Create an IPv4 network from an address and prefix length.
+
+
+ network_v4 make_network_v4(
+ const address_v4 & addr,
+ unsigned short prefix_len);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::make_network_v4 (2 of 2 overloads)]
+
+
+Create an IPv4 network from an address and netmask.
+
+
+ network_v4 make_network_v4(
+ const address_v4 & addr,
+ const address_v4 & mask);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:netmask ip::address_v4::netmask]
+
+[indexterm2 asio.indexterm.ip__address_v4.netmask..netmask..ip::address_v4]
+(Deprecated: Use [link asio.reference.ip__network_v4 `ip::network_v4`] class.) Obtain the netmask that corresponds to the address, based on its address class.
+
+
+ static address_v4 netmask(
+ const address_v4 & addr);
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::address_v4::operator!=]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_not__eq_..operator!=..ip::address_v4]
+Compare two addresses for inequality.
+
+
+ friend bool operator!=(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ ip::address_v4::operator<]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_lt_..operator<..ip::address_v4]
+Compare addresses for ordering.
+
+
+ friend bool operator<(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_lt__lt_ ip::address_v4::operator<<]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_lt__lt_..operator<<..ip::address_v4]
+Output an address as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & ``[link asio.reference.ip__address_v4.operator_lt__lt_.overload1 operator<<]``(
+ std::basic_ostream< Elem, Traits > & os,
+ const address_v4 & addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.operator_lt__lt_.overload1 more...]]``
+
+
+Output a network as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & ``[link asio.reference.ip__address_v4.operator_lt__lt_.overload2 operator<<]``(
+ std::basic_ostream< Elem, Traits > & os,
+ const network_v4 & net);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.operator_lt__lt_.overload2 more...]]``
+
+
+[section:overload1 ip::address_v4::operator<< (1 of 2 overloads)]
+
+
+Output an address as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const address_v4 & addr);
+
+
+Used to output a human-readable string for a specified address.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[addr][The address to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::operator<< (2 of 2 overloads)]
+
+
+Output a network as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const network_v4 & net);
+
+
+Used to output a human-readable string for a specified network.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[net][The network to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_lt__eq_ ip::address_v4::operator<=]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_lt__eq_..operator<=..ip::address_v4]
+Compare addresses for ordering.
+
+
+ friend bool operator<=(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::address_v4::operator=]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_eq_..operator=..ip::address_v4]
+Assign from another address.
+
+
+ address_v4 & operator=(
+ const address_v4 & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::address_v4::operator==]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_eq__eq_..operator==..ip::address_v4]
+Compare two addresses for equality.
+
+
+ friend bool operator==(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ ip::address_v4::operator>]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_gt_..operator>..ip::address_v4]
+Compare addresses for ordering.
+
+
+ friend bool operator>(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::address_v4::operator>=]
+
+[indexterm2 asio.indexterm.ip__address_v4.operator_gt__eq_..operator>=..ip::address_v4]
+Compare addresses for ordering.
+
+
+ friend bool operator>=(
+ const address_v4 & a1,
+ const address_v4 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:to_bytes ip::address_v4::to_bytes]
+
+[indexterm2 asio.indexterm.ip__address_v4.to_bytes..to_bytes..ip::address_v4]
+Get the address in bytes, in network byte order.
+
+
+ bytes_type to_bytes() const;
+
+
+
+[endsect]
+
+
+[section:to_string ip::address_v4::to_string]
+
+[indexterm2 asio.indexterm.ip__address_v4.to_string..to_string..ip::address_v4]
+Get the address as a string in dotted decimal format.
+
+
+ std::string ``[link asio.reference.ip__address_v4.to_string.overload1 to_string]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.to_string.overload1 more...]]``
+
+
+(Deprecated: Use other overload.) Get the address as a string in dotted decimal format.
+
+
+ std::string ``[link asio.reference.ip__address_v4.to_string.overload2 to_string]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.ip__address_v4.to_string.overload2 more...]]``
+
+
+[section:overload1 ip::address_v4::to_string (1 of 2 overloads)]
+
+
+Get the address as a string in dotted decimal format.
+
+
+ std::string to_string() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v4::to_string (2 of 2 overloads)]
+
+
+(Deprecated: Use other overload.) Get the address as a string in dotted decimal format.
+
+
+ std::string to_string(
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:to_uint ip::address_v4::to_uint]
+
+[indexterm2 asio.indexterm.ip__address_v4.to_uint..to_uint..ip::address_v4]
+Get the address as an unsigned integer in host byte order.
+
+
+ uint_type to_uint() const;
+
+
+
+[endsect]
+
+
+
+[section:to_ulong ip::address_v4::to_ulong]
+
+[indexterm2 asio.indexterm.ip__address_v4.to_ulong..to_ulong..ip::address_v4]
+Get the address as an unsigned long in host byte order.
+
+
+ unsigned long to_ulong() const;
+
+
+
+[endsect]
+
+
+
+[section:uint_type ip::address_v4::uint_type]
+
+[indexterm2 asio.indexterm.ip__address_v4.uint_type..uint_type..ip::address_v4]
+The type used to represent an address as an unsigned integer.
+
+
+ typedef uint_least32_t uint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ip__address_v4_iterator ip::address_v4_iterator]
+
+[indexterm1 asio.indexterm.ip__address_v4_iterator..ip::address_v4_iterator]
+An input iterator that can be used for traversing IPv4 addresses.
+
+
+ typedef basic_address_iterator< address_v4 > address_v4_iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__address_v4_range ip::address_v4_range]
+
+[indexterm1 asio.indexterm.ip__address_v4_range..ip::address_v4_range]
+Represents a range of IPv4 addresses.
+
+
+ typedef basic_address_range< address_v4 > address_v4_range;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:ip__address_v6 ip::address_v6]
+
+
+Implements IP version 6 style addresses.
+
+
+ class address_v6
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:address_v6 ip::address_v6::address_v6]
+
+[indexterm2 asio.indexterm.ip__address_v6.address_v6..address_v6..ip::address_v6]
+Default constructor.
+
+
+ ``[link asio.reference.ip__address_v6.address_v6.overload1 address_v6]``();
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.address_v6.overload1 more...]]``
+
+
+Construct an address from raw bytes and scope ID.
+
+
+ explicit ``[link asio.reference.ip__address_v6.address_v6.overload2 address_v6]``(
+ const bytes_type & bytes,
+ unsigned long scope_id = 0);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.address_v6.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__address_v6.address_v6.overload3 address_v6]``(
+ const address_v6 & other);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.address_v6.overload3 more...]]``
+
+
+[section:overload1 ip::address_v6::address_v6 (1 of 3 overloads)]
+
+
+Default constructor.
+
+
+ address_v6();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::address_v6 (2 of 3 overloads)]
+
+
+Construct an address from raw bytes and scope ID.
+
+
+ address_v6(
+ const bytes_type & bytes,
+ unsigned long scope_id = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v6::address_v6 (3 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ address_v6(
+ const address_v6 & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:any ip::address_v6::any]
+
+[indexterm2 asio.indexterm.ip__address_v6.any..any..ip::address_v6]
+Obtain an address object that represents any address.
+
+
+ static address_v6 any();
+
+
+
+[endsect]
+
+
+
+[section:bytes_type ip::address_v6::bytes_type]
+
+[indexterm2 asio.indexterm.ip__address_v6.bytes_type..bytes_type..ip::address_v6]
+The type used to represent an address as an array of bytes.
+
+
+ typedef array< unsigned char, 16 > bytes_type;
+
+
+
+
+[heading Remarks]
+
+This type is defined in terms of the C++0x template `std::array` when it is available. Otherwise, it uses `boost:array`.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:from_string ip::address_v6::from_string]
+
+[indexterm2 asio.indexterm.ip__address_v6.from_string..from_string..ip::address_v6]
+(Deprecated: Use `make_address_v6()`.) Create an IPv6 address from an IP address string.
+
+
+ static address_v6 ``[link asio.reference.ip__address_v6.from_string.overload1 from_string]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.from_string.overload1 more...]]``
+
+ static address_v6 ``[link asio.reference.ip__address_v6.from_string.overload2 from_string]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.from_string.overload2 more...]]``
+
+ static address_v6 ``[link asio.reference.ip__address_v6.from_string.overload3 from_string]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.from_string.overload3 more...]]``
+
+ static address_v6 ``[link asio.reference.ip__address_v6.from_string.overload4 from_string]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.from_string.overload4 more...]]``
+
+
+[section:overload1 ip::address_v6::from_string (1 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v6()`.) Create an IPv6 address from an IP address string.
+
+
+ static address_v6 from_string(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::from_string (2 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v6()`.) Create an IPv6 address from an IP address string.
+
+
+ static address_v6 from_string(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v6::from_string (3 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v6()`.) Create an IPv6 address from an IP address string.
+
+
+ static address_v6 from_string(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address_v6::from_string (4 of 4 overloads)]
+
+
+(Deprecated: Use `make_address_v6()`.) Create an IPv6 address from an IP address string.
+
+
+ static address_v6 from_string(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_link_local ip::address_v6::is_link_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_link_local..is_link_local..ip::address_v6]
+Determine whether the address is link local.
+
+
+ bool is_link_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_loopback ip::address_v6::is_loopback]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_loopback..is_loopback..ip::address_v6]
+Determine whether the address is a loopback address.
+
+
+ bool is_loopback() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast ip::address_v6::is_multicast]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast..is_multicast..ip::address_v6]
+Determine whether the address is a multicast address.
+
+
+ bool is_multicast() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast_global ip::address_v6::is_multicast_global]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast_global..is_multicast_global..ip::address_v6]
+Determine whether the address is a global multicast address.
+
+
+ bool is_multicast_global() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast_link_local ip::address_v6::is_multicast_link_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast_link_local..is_multicast_link_local..ip::address_v6]
+Determine whether the address is a link-local multicast address.
+
+
+ bool is_multicast_link_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast_node_local ip::address_v6::is_multicast_node_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast_node_local..is_multicast_node_local..ip::address_v6]
+Determine whether the address is a node-local multicast address.
+
+
+ bool is_multicast_node_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast_org_local ip::address_v6::is_multicast_org_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast_org_local..is_multicast_org_local..ip::address_v6]
+Determine whether the address is a org-local multicast address.
+
+
+ bool is_multicast_org_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_multicast_site_local ip::address_v6::is_multicast_site_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_multicast_site_local..is_multicast_site_local..ip::address_v6]
+Determine whether the address is a site-local multicast address.
+
+
+ bool is_multicast_site_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_site_local ip::address_v6::is_site_local]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_site_local..is_site_local..ip::address_v6]
+Determine whether the address is site local.
+
+
+ bool is_site_local() const;
+
+
+
+[endsect]
+
+
+
+[section:is_unspecified ip::address_v6::is_unspecified]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_unspecified..is_unspecified..ip::address_v6]
+Determine whether the address is unspecified.
+
+
+ bool is_unspecified() const;
+
+
+
+[endsect]
+
+
+
+[section:is_v4_compatible ip::address_v6::is_v4_compatible]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_v4_compatible..is_v4_compatible..ip::address_v6]
+(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address.
+
+
+ bool is_v4_compatible() const;
+
+
+
+[endsect]
+
+
+
+[section:is_v4_mapped ip::address_v6::is_v4_mapped]
+
+[indexterm2 asio.indexterm.ip__address_v6.is_v4_mapped..is_v4_mapped..ip::address_v6]
+Determine whether the address is a mapped IPv4 address.
+
+
+ bool is_v4_mapped() const;
+
+
+
+[endsect]
+
+
+
+[section:loopback ip::address_v6::loopback]
+
+[indexterm2 asio.indexterm.ip__address_v6.loopback..loopback..ip::address_v6]
+Obtain an address object that represents the loopback address.
+
+
+ static address_v6 loopback();
+
+
+
+[endsect]
+
+
+[section:make_address_v6 ip::address_v6::make_address_v6]
+
+[indexterm2 asio.indexterm.ip__address_v6.make_address_v6..make_address_v6..ip::address_v6]
+Create an IPv6 address from raw bytes and scope ID.
+
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload1 make_address_v6]``(
+ const address_v6::bytes_type & bytes,
+ unsigned long scope_id = 0);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload1 more...]]``
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload2 make_address_v6]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload2 more...]]``
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload3 make_address_v6]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload3 more...]]``
+
+
+Createan IPv6 address from an IP address string.
+
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload4 make_address_v6]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload4 more...]]``
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload5 make_address_v6]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload5 more...]]``
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload6 make_address_v6]``(
+ string_view str);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload6 more...]]``
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload7 make_address_v6]``(
+ string_view str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload7 more...]]``
+
+
+Create an IPv4-mapped IPv6 address from an IPv4 address.
+
+
+ address_v6 ``[link asio.reference.ip__address_v6.make_address_v6.overload8 make_address_v6]``(
+ v4_mapped_t ,
+ const address_v4 & v4_addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.make_address_v6.overload8 more...]]``
+
+
+[section:overload1 ip::address_v6::make_address_v6 (1 of 8 overloads)]
+
+
+Create an IPv6 address from raw bytes and scope ID.
+
+
+ address_v6 make_address_v6(
+ const address_v6::bytes_type & bytes,
+ unsigned long scope_id = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::make_address_v6 (2 of 8 overloads)]
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::address_v6::make_address_v6 (3 of 8 overloads)]
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::address_v6::make_address_v6 (4 of 8 overloads)]
+
+
+Createan IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::address_v6::make_address_v6 (5 of 8 overloads)]
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload6 ip::address_v6::make_address_v6 (6 of 8 overloads)]
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ string_view str);
+
+
+
+[endsect]
+
+
+
+[section:overload7 ip::address_v6::make_address_v6 (7 of 8 overloads)]
+
+
+Create an IPv6 address from an IP address string.
+
+
+ address_v6 make_address_v6(
+ string_view str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload8 ip::address_v6::make_address_v6 (8 of 8 overloads)]
+
+
+Create an IPv4-mapped IPv6 address from an IPv4 address.
+
+
+ address_v6 make_address_v6(
+ v4_mapped_t ,
+ const address_v4 & v4_addr);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:make_network_v6 ip::address_v6::make_network_v6]
+
+[indexterm2 asio.indexterm.ip__address_v6.make_network_v6..make_network_v6..ip::address_v6]
+Create an IPv6 network from an address and prefix length.
+
+
+ network_v6 make_network_v6(
+ const address_v6 & addr,
+ unsigned short prefix_len);
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::address_v6::operator!=]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_not__eq_..operator!=..ip::address_v6]
+Compare two addresses for inequality.
+
+
+ friend bool operator!=(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ ip::address_v6::operator<]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_lt_..operator<..ip::address_v6]
+Compare addresses for ordering.
+
+
+ friend bool operator<(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_lt__lt_ ip::address_v6::operator<<]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_lt__lt_..operator<<..ip::address_v6]
+Output an address as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & ``[link asio.reference.ip__address_v6.operator_lt__lt_.overload1 operator<<]``(
+ std::basic_ostream< Elem, Traits > & os,
+ const address_v6 & addr);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.operator_lt__lt_.overload1 more...]]``
+
+
+Output a network as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & ``[link asio.reference.ip__address_v6.operator_lt__lt_.overload2 operator<<]``(
+ std::basic_ostream< Elem, Traits > & os,
+ const network_v6 & net);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.operator_lt__lt_.overload2 more...]]``
+
+
+[section:overload1 ip::address_v6::operator<< (1 of 2 overloads)]
+
+
+Output an address as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const address_v6 & addr);
+
+
+Used to output a human-readable string for a specified address.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[addr][The address to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::operator<< (2 of 2 overloads)]
+
+
+Output a network as a string.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const network_v6 & net);
+
+
+Used to output a human-readable string for a specified network.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[net][The network to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_lt__eq_ ip::address_v6::operator<=]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_lt__eq_..operator<=..ip::address_v6]
+Compare addresses for ordering.
+
+
+ friend bool operator<=(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::address_v6::operator=]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_eq_..operator=..ip::address_v6]
+Assign from another address.
+
+
+ address_v6 & operator=(
+ const address_v6 & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::address_v6::operator==]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_eq__eq_..operator==..ip::address_v6]
+Compare two addresses for equality.
+
+
+ friend bool operator==(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ ip::address_v6::operator>]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_gt_..operator>..ip::address_v6]
+Compare addresses for ordering.
+
+
+ friend bool operator>(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::address_v6::operator>=]
+
+[indexterm2 asio.indexterm.ip__address_v6.operator_gt__eq_..operator>=..ip::address_v6]
+Compare addresses for ordering.
+
+
+ friend bool operator>=(
+ const address_v6 & a1,
+ const address_v6 & a2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:scope_id ip::address_v6::scope_id]
+
+[indexterm2 asio.indexterm.ip__address_v6.scope_id..scope_id..ip::address_v6]
+The scope ID of the address.
+
+
+ unsigned long ``[link asio.reference.ip__address_v6.scope_id.overload1 scope_id]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.scope_id.overload1 more...]]``
+
+ void ``[link asio.reference.ip__address_v6.scope_id.overload2 scope_id]``(
+ unsigned long id);
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.scope_id.overload2 more...]]``
+
+
+[section:overload1 ip::address_v6::scope_id (1 of 2 overloads)]
+
+
+The scope ID of the address.
+
+
+ unsigned long scope_id() const;
+
+
+Returns the scope ID associated with the IPv6 address.
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::scope_id (2 of 2 overloads)]
+
+
+The scope ID of the address.
+
+
+ void scope_id(
+ unsigned long id);
+
+
+Modifies the scope ID associated with the IPv6 address.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:to_bytes ip::address_v6::to_bytes]
+
+[indexterm2 asio.indexterm.ip__address_v6.to_bytes..to_bytes..ip::address_v6]
+Get the address in bytes, in network byte order.
+
+
+ bytes_type to_bytes() const;
+
+
+
+[endsect]
+
+
+[section:to_string ip::address_v6::to_string]
+
+[indexterm2 asio.indexterm.ip__address_v6.to_string..to_string..ip::address_v6]
+Get the address as a string.
+
+
+ std::string ``[link asio.reference.ip__address_v6.to_string.overload1 to_string]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.to_string.overload1 more...]]``
+
+
+(Deprecated: Use other overload.) Get the address as a string.
+
+
+ std::string ``[link asio.reference.ip__address_v6.to_string.overload2 to_string]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.ip__address_v6.to_string.overload2 more...]]``
+
+
+[section:overload1 ip::address_v6::to_string (1 of 2 overloads)]
+
+
+Get the address as a string.
+
+
+ std::string to_string() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::address_v6::to_string (2 of 2 overloads)]
+
+
+(Deprecated: Use other overload.) Get the address as a string.
+
+
+ std::string to_string(
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:to_v4 ip::address_v6::to_v4]
+
+[indexterm2 asio.indexterm.ip__address_v6.to_v4..to_v4..ip::address_v6]
+(Deprecated: Use `make_address_v4()`.) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address.
+
+
+ address_v4 to_v4() const;
+
+
+
+[endsect]
+
+
+
+[section:v4_compatible ip::address_v6::v4_compatible]
+
+[indexterm2 asio.indexterm.ip__address_v6.v4_compatible..v4_compatible..ip::address_v6]
+(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address.
+
+
+ static address_v6 v4_compatible(
+ const address_v4 & addr);
+
+
+
+[endsect]
+
+
+
+[section:v4_mapped ip::address_v6::v4_mapped]
+
+[indexterm2 asio.indexterm.ip__address_v6.v4_mapped..v4_mapped..ip::address_v6]
+(Deprecated: Use `make_address_v6()`.) Create an IPv4-mapped IPv6 address.
+
+
+ static address_v6 v4_mapped(
+ const address_v4 & addr);
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ip__address_v6_iterator ip::address_v6_iterator]
+
+[indexterm1 asio.indexterm.ip__address_v6_iterator..ip::address_v6_iterator]
+An input iterator that can be used for traversing IPv6 addresses.
+
+
+ typedef basic_address_iterator< address_v6 > address_v6_iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__address_v6_range ip::address_v6_range]
+
+[indexterm1 asio.indexterm.ip__address_v6_range..ip::address_v6_range]
+Represents a range of IPv6 addresses.
+
+
+ typedef basic_address_range< address_v6 > address_v6_range;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:ip__bad_address_cast ip::bad_address_cast]
+
+
+Thrown to indicate a failed address conversion.
+
+
+ class bad_address_cast
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__bad_address_cast.bad_address_cast [*bad_address_cast]]]
+ [Default constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__bad_address_cast.what [*what]]]
+ [Get the message associated with the exception. ]
+ ]
+
+ [
+ [[link asio.reference.ip__bad_address_cast._bad_address_cast [*~bad_address_cast]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ip/bad_address_cast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:bad_address_cast ip::bad_address_cast::bad_address_cast]
+
+[indexterm2 asio.indexterm.ip__bad_address_cast.bad_address_cast..bad_address_cast..ip::bad_address_cast]
+Default constructor.
+
+
+ bad_address_cast();
+
+
+
+[endsect]
+
+
+
+[section:what ip::bad_address_cast::what]
+
+[indexterm2 asio.indexterm.ip__bad_address_cast.what..what..ip::bad_address_cast]
+Get the message associated with the exception.
+
+
+ virtual const char * what() const;
+
+
+
+[endsect]
+
+
+
+[section:_bad_address_cast ip::bad_address_cast::~bad_address_cast]
+
+[indexterm2 asio.indexterm.ip__bad_address_cast._bad_address_cast..~bad_address_cast..ip::bad_address_cast]
+Destructor.
+
+
+ virtual ~bad_address_cast();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_address_iterator_lt__address_v4__gt_ ip::basic_address_iterator< address_v4 >]
+
+
+An input iterator that can be used for traversing IPv4 addresses.
+
+
+ template<>
+ class basic_address_iterator< address_v4 >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.difference_type [*difference_type]]]
+ [Distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.iterator_category [*iterator_category]]]
+ [Denotes that the iterator satisfies the input iterator requirements. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.pointer [*pointer]]]
+ [The type of a pointer to an element pointed to by the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.reference [*reference]]]
+ [The type of a reference to an element pointed to by the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.value_type [*value_type]]]
+ [The type of the elements pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator [*basic_address_iterator]]]
+ [Construct an iterator that points to the specified address.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator__star_ [*operator *]]]
+ [Dereference the iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_ [*operator++]]]
+ [Pre-increment operator.
+
+ Post-increment operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_ [*operator--]]]
+ [Pre-decrement operator.
+
+ Post-decrement operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_arrow_ [*operator->]]]
+ [Dereference the iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_eq_ [*operator=]]]
+ [Assignment operator. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+]
+
+In addition to satisfying the input iterator requirements, this iterator also supports decrement.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_address_iterator ip::basic_address_iterator< address_v4 >::basic_address_iterator]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator..basic_address_iterator..ip::basic_address_iterator< address_v4 >]
+Construct an iterator that points to the specified address.
+
+
+ ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator.overload1 basic_address_iterator]``(
+ const address_v4 & addr);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator.overload2 basic_address_iterator]``(
+ const basic_address_iterator & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.basic_address_iterator.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v4 >::basic_address_iterator (1 of 2 overloads)]
+
+
+Construct an iterator that points to the specified address.
+
+
+ basic_address_iterator(
+ const address_v4 & addr);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v4 >::basic_address_iterator (2 of 2 overloads)]
+
+
+Copy constructor.
+
+
+ basic_address_iterator(
+ const basic_address_iterator & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:difference_type ip::basic_address_iterator< address_v4 >::difference_type]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.difference_type..difference_type..ip::basic_address_iterator< address_v4 >]
+Distance between two iterators.
+
+
+ typedef std::ptrdiff_t difference_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:iterator_category ip::basic_address_iterator< address_v4 >::iterator_category]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.iterator_category..iterator_category..ip::basic_address_iterator< address_v4 >]
+Denotes that the iterator satisfies the input iterator requirements.
+
+
+ typedef std::input_iterator_tag iterator_category;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator__star_ ip::basic_address_iterator< address_v4 >::operator *]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator__star_..operator *..ip::basic_address_iterator< address_v4 >]
+Dereference the iterator.
+
+
+ const address_v4 & operator *() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::basic_address_iterator< address_v4 >::operator!=]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_not__eq_..operator!=..ip::basic_address_iterator< address_v4 >]
+Compare two addresses for inequality.
+
+
+ friend bool operator!=(
+ const basic_address_iterator & a,
+ const basic_address_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_plus__plus_ ip::basic_address_iterator< address_v4 >::operator++]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_..operator++..ip::basic_address_iterator< address_v4 >]
+Pre-increment operator.
+
+
+ basic_address_iterator & ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_.overload1 operator++]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_.overload1 more...]]``
+
+
+Post-increment operator.
+
+
+ basic_address_iterator ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_.overload2 operator++]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_plus__plus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v4 >::operator++ (1 of 2 overloads)]
+
+
+Pre-increment operator.
+
+
+ basic_address_iterator & operator++();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v4 >::operator++ (2 of 2 overloads)]
+
+
+Post-increment operator.
+
+
+ basic_address_iterator operator++(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_minus__minus_ ip::basic_address_iterator< address_v4 >::operator--]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_..operator--..ip::basic_address_iterator< address_v4 >]
+Pre-decrement operator.
+
+
+ basic_address_iterator & ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_.overload1 operator--]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_.overload1 more...]]``
+
+
+Post-decrement operator.
+
+
+ basic_address_iterator ``[link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_.overload2 operator--]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v4__gt_.operator_minus__minus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v4 >::operator-- (1 of 2 overloads)]
+
+
+Pre-decrement operator.
+
+
+ basic_address_iterator & operator--();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v4 >::operator-- (2 of 2 overloads)]
+
+
+Post-decrement operator.
+
+
+ basic_address_iterator operator--(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_arrow_ ip::basic_address_iterator< address_v4 >::operator->]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_arrow_..operator->..ip::basic_address_iterator< address_v4 >]
+Dereference the iterator.
+
+
+ const address_v4 * operator->() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::basic_address_iterator< address_v4 >::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_eq_..operator=..ip::basic_address_iterator< address_v4 >]
+Assignment operator.
+
+
+ basic_address_iterator & operator=(
+ const basic_address_iterator & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::basic_address_iterator< address_v4 >::operator==]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.operator_eq__eq_..operator==..ip::basic_address_iterator< address_v4 >]
+Compare two addresses for equality.
+
+
+ friend bool operator==(
+ const basic_address_iterator & a,
+ const basic_address_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:pointer ip::basic_address_iterator< address_v4 >::pointer]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.pointer..pointer..ip::basic_address_iterator< address_v4 >]
+The type of a pointer to an element pointed to by the iterator.
+
+
+ typedef const address_v4 * pointer;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reference ip::basic_address_iterator< address_v4 >::reference]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.reference..reference..ip::basic_address_iterator< address_v4 >]
+The type of a reference to an element pointed to by the iterator.
+
+
+ typedef const address_v4 & reference;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:value_type ip::basic_address_iterator< address_v4 >::value_type]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v4__gt_.value_type..value_type..ip::basic_address_iterator< address_v4 >]
+The type of the elements pointed to by the iterator.
+
+
+ typedef address_v4 value_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_address_iterator_lt__address_v6__gt_ ip::basic_address_iterator< address_v6 >]
+
+
+An input iterator that can be used for traversing IPv6 addresses.
+
+
+ template<>
+ class basic_address_iterator< address_v6 >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.difference_type [*difference_type]]]
+ [Distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.iterator_category [*iterator_category]]]
+ [Denotes that the iterator satisfies the input iterator requirements. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.pointer [*pointer]]]
+ [The type of a pointer to an element pointed to by the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.reference [*reference]]]
+ [The type of a reference to an element pointed to by the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.value_type [*value_type]]]
+ [The type of the elements pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator [*basic_address_iterator]]]
+ [Construct an iterator that points to the specified address.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator__star_ [*operator *]]]
+ [Dereference the iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_ [*operator++]]]
+ [Pre-increment operator.
+
+ Post-increment operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_ [*operator--]]]
+ [Pre-decrement operator.
+
+ Post-decrement operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_arrow_ [*operator->]]]
+ [Dereference the iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_eq_ [*operator=]]]
+ [Assignment operator. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+]
+
+In addition to satisfying the input iterator requirements, this iterator also supports decrement.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_address_iterator ip::basic_address_iterator< address_v6 >::basic_address_iterator]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator..basic_address_iterator..ip::basic_address_iterator< address_v6 >]
+Construct an iterator that points to the specified address.
+
+
+ ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator.overload1 basic_address_iterator]``(
+ const address_v6 & addr);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator.overload2 basic_address_iterator]``(
+ const basic_address_iterator & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.basic_address_iterator.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v6 >::basic_address_iterator (1 of 2 overloads)]
+
+
+Construct an iterator that points to the specified address.
+
+
+ basic_address_iterator(
+ const address_v6 & addr);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v6 >::basic_address_iterator (2 of 2 overloads)]
+
+
+Copy constructor.
+
+
+ basic_address_iterator(
+ const basic_address_iterator & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:difference_type ip::basic_address_iterator< address_v6 >::difference_type]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.difference_type..difference_type..ip::basic_address_iterator< address_v6 >]
+Distance between two iterators.
+
+
+ typedef std::ptrdiff_t difference_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:iterator_category ip::basic_address_iterator< address_v6 >::iterator_category]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.iterator_category..iterator_category..ip::basic_address_iterator< address_v6 >]
+Denotes that the iterator satisfies the input iterator requirements.
+
+
+ typedef std::input_iterator_tag iterator_category;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator__star_ ip::basic_address_iterator< address_v6 >::operator *]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator__star_..operator *..ip::basic_address_iterator< address_v6 >]
+Dereference the iterator.
+
+
+ const address_v6 & operator *() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::basic_address_iterator< address_v6 >::operator!=]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_not__eq_..operator!=..ip::basic_address_iterator< address_v6 >]
+Compare two addresses for inequality.
+
+
+ friend bool operator!=(
+ const basic_address_iterator & a,
+ const basic_address_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_plus__plus_ ip::basic_address_iterator< address_v6 >::operator++]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_..operator++..ip::basic_address_iterator< address_v6 >]
+Pre-increment operator.
+
+
+ basic_address_iterator & ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_.overload1 operator++]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_.overload1 more...]]``
+
+
+Post-increment operator.
+
+
+ basic_address_iterator ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_.overload2 operator++]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_plus__plus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v6 >::operator++ (1 of 2 overloads)]
+
+
+Pre-increment operator.
+
+
+ basic_address_iterator & operator++();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v6 >::operator++ (2 of 2 overloads)]
+
+
+Post-increment operator.
+
+
+ basic_address_iterator operator++(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_minus__minus_ ip::basic_address_iterator< address_v6 >::operator--]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_..operator--..ip::basic_address_iterator< address_v6 >]
+Pre-decrement operator.
+
+
+ basic_address_iterator & ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_.overload1 operator--]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_.overload1 more...]]``
+
+
+Post-decrement operator.
+
+
+ basic_address_iterator ``[link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_.overload2 operator--]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_iterator_lt__address_v6__gt_.operator_minus__minus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_address_iterator< address_v6 >::operator-- (1 of 2 overloads)]
+
+
+Pre-decrement operator.
+
+
+ basic_address_iterator & operator--();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_iterator< address_v6 >::operator-- (2 of 2 overloads)]
+
+
+Post-decrement operator.
+
+
+ basic_address_iterator operator--(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_arrow_ ip::basic_address_iterator< address_v6 >::operator->]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_arrow_..operator->..ip::basic_address_iterator< address_v6 >]
+Dereference the iterator.
+
+
+ const address_v6 * operator->() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::basic_address_iterator< address_v6 >::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_eq_..operator=..ip::basic_address_iterator< address_v6 >]
+Assignment operator.
+
+
+ basic_address_iterator & operator=(
+ const basic_address_iterator & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::basic_address_iterator< address_v6 >::operator==]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.operator_eq__eq_..operator==..ip::basic_address_iterator< address_v6 >]
+Compare two addresses for equality.
+
+
+ friend bool operator==(
+ const basic_address_iterator & a,
+ const basic_address_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:pointer ip::basic_address_iterator< address_v6 >::pointer]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.pointer..pointer..ip::basic_address_iterator< address_v6 >]
+The type of a pointer to an element pointed to by the iterator.
+
+
+ typedef const address_v6 * pointer;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reference ip::basic_address_iterator< address_v6 >::reference]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.reference..reference..ip::basic_address_iterator< address_v6 >]
+The type of a reference to an element pointed to by the iterator.
+
+
+ typedef const address_v6 & reference;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:value_type ip::basic_address_iterator< address_v6 >::value_type]
+
+[indexterm2 asio.indexterm.ip__basic_address_iterator_lt__address_v6__gt_.value_type..value_type..ip::basic_address_iterator< address_v6 >]
+The type of the elements pointed to by the iterator.
+
+
+ typedef address_v6 value_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_address_range_lt__address_v4__gt_ ip::basic_address_range< address_v4 >]
+
+
+Represents a range of IPv4 addresses.
+
+
+ template<>
+ class basic_address_range< address_v4 >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.iterator [*iterator]]]
+ [The type of an iterator that points into the range. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range [*basic_address_range]]]
+ [Construct an empty range.
+
+ Construct an range that represents the given range of addresses.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.begin [*begin]]]
+ [Obtain an iterator that points to the start of the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.empty [*empty]]]
+ [Determine whether the range is empty. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.end [*end]]]
+ [Obtain an iterator that points to the end of the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.find [*find]]]
+ [Find an address in the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.operator_eq_ [*operator=]]]
+ [Assignment operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.size [*size]]]
+ [Return the size of the range. ]
+ ]
+
+]
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_address_range ip::basic_address_range< address_v4 >::basic_address_range]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.basic_address_range..basic_address_range..ip::basic_address_range< address_v4 >]
+Construct an empty range.
+
+
+ ``[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload1 basic_address_range]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload1 more...]]``
+
+
+Construct an range that represents the given range of addresses.
+
+
+ explicit ``[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload2 basic_address_range]``(
+ const iterator & first,
+ const iterator & last);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload3 basic_address_range]``(
+ const basic_address_range & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v4__gt_.basic_address_range.overload3 more...]]``
+
+
+[section:overload1 ip::basic_address_range< address_v4 >::basic_address_range (1 of 3 overloads)]
+
+
+Construct an empty range.
+
+
+ basic_address_range();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_range< address_v4 >::basic_address_range (2 of 3 overloads)]
+
+
+Construct an range that represents the given range of addresses.
+
+
+ basic_address_range(
+ const iterator & first,
+ const iterator & last);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_address_range< address_v4 >::basic_address_range (3 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ basic_address_range(
+ const basic_address_range & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:begin ip::basic_address_range< address_v4 >::begin]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.begin..begin..ip::basic_address_range< address_v4 >]
+Obtain an iterator that points to the start of the range.
+
+
+ iterator begin() const;
+
+
+
+[endsect]
+
+
+
+[section:empty ip::basic_address_range< address_v4 >::empty]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.empty..empty..ip::basic_address_range< address_v4 >]
+Determine whether the range is empty.
+
+
+ bool empty() const;
+
+
+
+[endsect]
+
+
+
+[section:end ip::basic_address_range< address_v4 >::end]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.end..end..ip::basic_address_range< address_v4 >]
+Obtain an iterator that points to the end of the range.
+
+
+ iterator end() const;
+
+
+
+[endsect]
+
+
+
+[section:find ip::basic_address_range< address_v4 >::find]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.find..find..ip::basic_address_range< address_v4 >]
+Find an address in the range.
+
+
+ iterator find(
+ const address_v4 & addr) const;
+
+
+
+[endsect]
+
+
+
+[section:iterator ip::basic_address_range< address_v4 >::iterator]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.iterator..iterator..ip::basic_address_range< address_v4 >]
+The type of an iterator that points into the range.
+
+
+ typedef basic_address_iterator< address_v4 > iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v4.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__address_v4.uint_type [*uint_type]]]
+ [The type used to represent an address as an unsigned integer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.address_v4 [*address_v4]]]
+ [Default constructor.
+
+ Construct an address from raw bytes.
+
+ Construct an address from an unsigned integer in host byte order.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the broadcast address.
+
+ (Deprecated: Use network_v4 class.) Obtain an address object that represents the broadcast address that corresponds to the specified address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v4().) Create an address from an IP address string in dotted decimal form. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_a [*is_class_a]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class A address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_b [*is_class_b]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class B address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_class_c [*is_class_c]]]
+ [(Deprecated: Use network_v4 class.) Determine whether the address is a class C address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.netmask [*netmask]]]
+ [(Deprecated: Use network_v4 class.) Obtain the netmask that corresponds to the address, based on its address class. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_string [*to_string]]]
+ [Get the address as a string in dotted decimal format.
+
+ (Deprecated: Use other overload.) Get the address as a string in dotted decimal format. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_uint [*to_uint]]]
+ [Get the address as an unsigned integer in host byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.to_ulong [*to_ulong]]]
+ [Get the address as an unsigned long in host byte order. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v4.make_address_v4 [*make_address_v4]]]
+ [Create an IPv4 address from raw bytes in network order.
+
+ Create an IPv4 address from an unsigned integer in host byte order.
+
+ Create an IPv4 address from an IP address string in dotted decimal form.
+
+ Create an IPv4 address from a IPv4-mapped IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from an address and prefix length.
+
+ Create an IPv4 network from an address and netmask. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v4.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v4 `ip::address_v4`] class provides the ability to use and manipulate IP version 4 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v4_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::basic_address_range< address_v4 >::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.operator_eq_..operator=..ip::basic_address_range< address_v4 >]
+Assignment operator.
+
+
+ basic_address_range & operator=(
+ const basic_address_range & other);
+
+
+
+[endsect]
+
+
+
+[section:size ip::basic_address_range< address_v4 >::size]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v4__gt_.size..size..ip::basic_address_range< address_v4 >]
+Return the size of the range.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_address_range_lt__address_v6__gt_ ip::basic_address_range< address_v6 >]
+
+
+Represents a range of IPv6 addresses.
+
+
+ template<>
+ class basic_address_range< address_v6 >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.iterator [*iterator]]]
+ [The type of an iterator that points into the range. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range [*basic_address_range]]]
+ [Construct an empty range.
+
+ Construct an range that represents the given range of addresses.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.begin [*begin]]]
+ [Obtain an iterator that points to the start of the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.empty [*empty]]]
+ [Determine whether the range is empty. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.end [*end]]]
+ [Obtain an iterator that points to the end of the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.find [*find]]]
+ [Find an address in the range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.operator_eq_ [*operator=]]]
+ [Assignment operator. ]
+ ]
+
+]
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_address_range ip::basic_address_range< address_v6 >::basic_address_range]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.basic_address_range..basic_address_range..ip::basic_address_range< address_v6 >]
+Construct an empty range.
+
+
+ ``[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload1 basic_address_range]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload1 more...]]``
+
+
+Construct an range that represents the given range of addresses.
+
+
+ explicit ``[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload2 basic_address_range]``(
+ const iterator & first,
+ const iterator & last);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload3 basic_address_range]``(
+ const basic_address_range & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_address_range_lt__address_v6__gt_.basic_address_range.overload3 more...]]``
+
+
+[section:overload1 ip::basic_address_range< address_v6 >::basic_address_range (1 of 3 overloads)]
+
+
+Construct an empty range.
+
+
+ basic_address_range();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_address_range< address_v6 >::basic_address_range (2 of 3 overloads)]
+
+
+Construct an range that represents the given range of addresses.
+
+
+ basic_address_range(
+ const iterator & first,
+ const iterator & last);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_address_range< address_v6 >::basic_address_range (3 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ basic_address_range(
+ const basic_address_range & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:begin ip::basic_address_range< address_v6 >::begin]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.begin..begin..ip::basic_address_range< address_v6 >]
+Obtain an iterator that points to the start of the range.
+
+
+ iterator begin() const;
+
+
+
+[endsect]
+
+
+
+[section:empty ip::basic_address_range< address_v6 >::empty]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.empty..empty..ip::basic_address_range< address_v6 >]
+Determine whether the range is empty.
+
+
+ bool empty() const;
+
+
+
+[endsect]
+
+
+
+[section:end ip::basic_address_range< address_v6 >::end]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.end..end..ip::basic_address_range< address_v6 >]
+Obtain an iterator that points to the end of the range.
+
+
+ iterator end() const;
+
+
+
+[endsect]
+
+
+
+[section:find ip::basic_address_range< address_v6 >::find]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.find..find..ip::basic_address_range< address_v6 >]
+Find an address in the range.
+
+
+ iterator find(
+ const address_v6 & addr) const;
+
+
+
+[endsect]
+
+
+
+[section:iterator ip::basic_address_range< address_v6 >::iterator]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.iterator..iterator..ip::basic_address_range< address_v6 >]
+The type of an iterator that points into the range.
+
+
+ typedef basic_address_iterator< address_v6 > iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__address_v6.bytes_type [*bytes_type]]]
+ [The type used to represent an address as an array of bytes. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.address_v6 [*address_v6]]]
+ [Default constructor.
+
+ Construct an address from raw bytes and scope ID.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.any [*any]]]
+ [Obtain an address object that represents any address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.from_string [*from_string]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv6 address from an IP address string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_link_local [*is_link_local]]]
+ [Determine whether the address is link local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_loopback [*is_loopback]]]
+ [Determine whether the address is a loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast [*is_multicast]]]
+ [Determine whether the address is a multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_global [*is_multicast_global]]]
+ [Determine whether the address is a global multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_link_local [*is_multicast_link_local]]]
+ [Determine whether the address is a link-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_node_local [*is_multicast_node_local]]]
+ [Determine whether the address is a node-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_org_local [*is_multicast_org_local]]]
+ [Determine whether the address is a org-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_multicast_site_local [*is_multicast_site_local]]]
+ [Determine whether the address is a site-local multicast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_site_local [*is_site_local]]]
+ [Determine whether the address is site local. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_unspecified [*is_unspecified]]]
+ [Determine whether the address is unspecified. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_compatible [*is_v4_compatible]]]
+ [(Deprecated: No replacement.) Determine whether the address is an IPv4-compatible address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.is_v4_mapped [*is_v4_mapped]]]
+ [Determine whether the address is a mapped IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.loopback [*loopback]]]
+ [Obtain an address object that represents the loopback address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq_ [*operator=]]]
+ [Assign from another address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.scope_id [*scope_id]]]
+ [The scope ID of the address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_bytes [*to_bytes]]]
+ [Get the address in bytes, in network byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_string [*to_string]]]
+ [Get the address as a string.
+
+ (Deprecated: Use other overload.) Get the address as a string. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.to_v4 [*to_v4]]]
+ [(Deprecated: Use make_address_v4().) Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_compatible [*v4_compatible]]]
+ [(Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.v4_mapped [*v4_mapped]]]
+ [(Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two addresses for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt_ [*operator<]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two addresses for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__address_v6.make_address_v6 [*make_address_v6]]]
+ [Create an IPv6 address from raw bytes and scope ID.
+
+ Create an IPv6 address from an IP address string.
+
+ Createan IPv6 address from an IP address string.
+
+ Create an IPv4-mapped IPv6 address from an IPv4 address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from an address and prefix length. ]
+ ]
+
+ [
+ [[link asio.reference.ip__address_v6.operator_lt__lt_ [*operator<<]]]
+ [Output an address as a string.
+
+ Output a network as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__address_v6 `ip::address_v6`] class provides the ability to use and manipulate IP version 6 addresses.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6_range.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::basic_address_range< address_v6 >::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_address_range_lt__address_v6__gt_.operator_eq_..operator=..ip::basic_address_range< address_v6 >]
+Assignment operator.
+
+
+ basic_address_range & operator=(
+ const basic_address_range & other);
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_endpoint ip::basic_endpoint]
+
+
+Describes an endpoint for a version-independent IP socket.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_endpoint
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.address [*address]]]
+ [Get the IP address associated with the endpoint.
+
+ Set the IP address associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR_ANY or in6addr_any). This constructor would typically be used for accepting new connections.
+
+ Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint.
+
+ Move-assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.port [*port]]]
+ [Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+ Set the port associated with the endpoint. The port number is always in the host's byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_endpoint `ip::basic_endpoint`] class template describes an endpoint that may be associated with a particular socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:address ip::basic_endpoint::address]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.address..address..ip::basic_endpoint]
+Get the IP address associated with the endpoint.
+
+
+ asio::ip::address ``[link asio.reference.ip__basic_endpoint.address.overload1 address]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.address.overload1 more...]]``
+
+
+Set the IP address associated with the endpoint.
+
+
+ void ``[link asio.reference.ip__basic_endpoint.address.overload2 address]``(
+ const asio::ip::address & addr);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.address.overload2 more...]]``
+
+
+[section:overload1 ip::basic_endpoint::address (1 of 2 overloads)]
+
+
+Get the IP address associated with the endpoint.
+
+
+ asio::ip::address address() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_endpoint::address (2 of 2 overloads)]
+
+
+Set the IP address associated with the endpoint.
+
+
+ void address(
+ const asio::ip::address & addr);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_endpoint ip::basic_endpoint::basic_endpoint]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.basic_endpoint..basic_endpoint..ip::basic_endpoint]
+Default constructor.
+
+
+ ``[link asio.reference.ip__basic_endpoint.basic_endpoint.overload1 basic_endpoint]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.basic_endpoint.overload1 more...]]``
+
+
+Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR\_ANY or in6addr\_any). This constructor would typically be used for accepting new connections.
+
+
+ ``[link asio.reference.ip__basic_endpoint.basic_endpoint.overload2 basic_endpoint]``(
+ const InternetProtocol & internet_protocol,
+ unsigned short port_num);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.basic_endpoint.overload2 more...]]``
+
+
+Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+
+ ``[link asio.reference.ip__basic_endpoint.basic_endpoint.overload3 basic_endpoint]``(
+ const asio::ip::address & addr,
+ unsigned short port_num);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.basic_endpoint.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_endpoint.basic_endpoint.overload4 basic_endpoint]``(
+ const basic_endpoint & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.basic_endpoint.overload4 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.ip__basic_endpoint.basic_endpoint.overload5 basic_endpoint]``(
+ basic_endpoint && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.basic_endpoint.overload5 more...]]``
+
+
+[section:overload1 ip::basic_endpoint::basic_endpoint (1 of 5 overloads)]
+
+
+Default constructor.
+
+
+ basic_endpoint();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_endpoint::basic_endpoint (2 of 5 overloads)]
+
+
+Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR\_ANY or in6addr\_any). This constructor would typically be used for accepting new connections.
+
+
+ basic_endpoint(
+ const InternetProtocol & internet_protocol,
+ unsigned short port_num);
+
+
+
+[heading Examples]
+
+To initialise an IPv4 TCP endpoint for port 1234, use:
+
+ asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 1234);
+
+
+
+
+To specify an IPv6 UDP endpoint for port 9876, use:
+
+ asio::ip::udp::endpoint ep(asio::ip::udp::v6(), 9876);
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_endpoint::basic_endpoint (3 of 5 overloads)]
+
+
+Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+
+ basic_endpoint(
+ const asio::ip::address & addr,
+ unsigned short port_num);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::basic_endpoint::basic_endpoint (4 of 5 overloads)]
+
+
+Copy constructor.
+
+
+ basic_endpoint(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::basic_endpoint::basic_endpoint (5 of 5 overloads)]
+
+
+Move constructor.
+
+
+ basic_endpoint(
+ basic_endpoint && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:capacity ip::basic_endpoint::capacity]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.capacity..capacity..ip::basic_endpoint]
+Get the capacity of the endpoint in the native type.
+
+
+ std::size_t capacity() const;
+
+
+
+[endsect]
+
+
+[section:data ip::basic_endpoint::data]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.data..data..ip::basic_endpoint]
+Get the underlying endpoint in the native type.
+
+
+ data_type * ``[link asio.reference.ip__basic_endpoint.data.overload1 data]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.data.overload1 more...]]``
+
+ const data_type * ``[link asio.reference.ip__basic_endpoint.data.overload2 data]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.data.overload2 more...]]``
+
+
+[section:overload1 ip::basic_endpoint::data (1 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ data_type * data();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_endpoint::data (2 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ const data_type * data() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:data_type ip::basic_endpoint::data_type]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.data_type..data_type..ip::basic_endpoint]
+The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer.
+
+
+ typedef implementation_defined data_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::basic_endpoint::operator!=]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_not__eq_..operator!=..ip::basic_endpoint]
+Compare two endpoints for inequality.
+
+
+ friend bool operator!=(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ ip::basic_endpoint::operator<]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_lt_..operator<..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt__lt_ ip::basic_endpoint::operator<<]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_lt__lt_..operator<<..ip::basic_endpoint]
+Output an endpoint as a string.
+
+
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const basic_endpoint< InternetProtocol > & endpoint);
+
+
+Used to output a human-readable string for a specified endpoint.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[endpoint][The endpoint to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_lt__eq_ ip::basic_endpoint::operator<=]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_lt__eq_..operator<=..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<=(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_eq_ ip::basic_endpoint::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_eq_..operator=..ip::basic_endpoint]
+Assign from another endpoint.
+
+
+ basic_endpoint & ``[link asio.reference.ip__basic_endpoint.operator_eq_.overload1 operator=]``(
+ const basic_endpoint & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.operator_eq_.overload1 more...]]``
+
+
+Move-assign from another endpoint.
+
+
+ basic_endpoint & ``[link asio.reference.ip__basic_endpoint.operator_eq_.overload2 operator=]``(
+ basic_endpoint && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_endpoint::operator= (1 of 2 overloads)]
+
+
+Assign from another endpoint.
+
+
+ basic_endpoint & operator=(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_endpoint::operator= (2 of 2 overloads)]
+
+
+Move-assign from another endpoint.
+
+
+ basic_endpoint & operator=(
+ basic_endpoint && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq__eq_ ip::basic_endpoint::operator==]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_eq__eq_..operator==..ip::basic_endpoint]
+Compare two endpoints for equality.
+
+
+ friend bool operator==(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ ip::basic_endpoint::operator>]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_gt_..operator>..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::basic_endpoint::operator>=]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.operator_gt__eq_..operator>=..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>=(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:port ip::basic_endpoint::port]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.port..port..ip::basic_endpoint]
+Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+
+ unsigned short ``[link asio.reference.ip__basic_endpoint.port.overload1 port]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.port.overload1 more...]]``
+
+
+Set the port associated with the endpoint. The port number is always in the host's byte order.
+
+
+ void ``[link asio.reference.ip__basic_endpoint.port.overload2 port]``(
+ unsigned short port_num);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_endpoint.port.overload2 more...]]``
+
+
+[section:overload1 ip::basic_endpoint::port (1 of 2 overloads)]
+
+
+Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+
+ unsigned short port() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_endpoint::port (2 of 2 overloads)]
+
+
+Set the port associated with the endpoint. The port number is always in the host's byte order.
+
+
+ void port(
+ unsigned short port_num);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol ip::basic_endpoint::protocol]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.protocol..protocol..ip::basic_endpoint]
+The protocol associated with the endpoint.
+
+
+ protocol_type protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type ip::basic_endpoint::protocol_type]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.protocol_type..protocol_type..ip::basic_endpoint]
+The protocol type associated with the endpoint.
+
+
+ typedef InternetProtocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:resize ip::basic_endpoint::resize]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.resize..resize..ip::basic_endpoint]
+Set the underlying size of the endpoint in the native type.
+
+
+ void resize(
+ std::size_t new_size);
+
+
+
+[endsect]
+
+
+
+[section:size ip::basic_endpoint::size]
+
+[indexterm2 asio.indexterm.ip__basic_endpoint.size..size..ip::basic_endpoint]
+Get the underlying size of the endpoint in the native type.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_resolver ip::basic_resolver]
+
+
+Provides endpoint resolution functionality.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_resolver :
+ public ip::resolver_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.iterator [*iterator]]]
+ [(Deprecated.) The iterator type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.query [*query]]]
+ [(Deprecated.) The query type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.results_type [*results_type]]]
+ [The results type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.async_resolve [*async_resolve]]]
+ [(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.basic_resolver [*basic_resolver]]]
+ [Constructor.
+
+ Move-construct a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the resolver. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.operator_eq_ [*operator=]]]
+ [Move-assign a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.resolve [*resolve]]]
+ [(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+ Perform forward resolution of a query to a list of entries.
+
+ Perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver._basic_resolver [*~basic_resolver]]]
+ [Destroys the resolver. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver `ip::basic_resolver`] class template provides the ability to resolve a query to a list of endpoints.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address_configured ip::basic_resolver::address_configured]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.address_configured..address_configured..ip::basic_resolver]
+Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system.
+
+
+ static const flags address_configured = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:all_matching ip::basic_resolver::all_matching]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.all_matching..all_matching..ip::basic_resolver]
+If used with v4\_mapped, return all matching IPv6 and IPv4 addresses.
+
+
+ static const flags all_matching = implementation_defined;
+
+
+
+[endsect]
+
+
+[section:async_resolve ip::basic_resolver::async_resolve]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.async_resolve..async_resolve..ip::basic_resolver]
+(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload1 async_resolve]``(
+ const query & q,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload1 more...]]``
+
+
+Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload2 async_resolve]``(
+ string_view host,
+ string_view service,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload3 async_resolve]``(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload4 async_resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload5 async_resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload5 more...]]``
+
+
+Asynchronously perform reverse resolution of an endpoint to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ip__basic_resolver.async_resolve.overload6 async_resolve]``(
+ const endpoint_type & e,
+ ResolveHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.async_resolve.overload6 more...]]``
+
+
+[section:overload1 ip::basic_resolver::async_resolve (1 of 6 overloads)]
+
+
+(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ const query & q,
+ ResolveHandler && handler);
+
+
+This function is used to asynchronously resolve a query into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[q][A query object that determines what endpoints will be returned.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver::async_resolve (2 of 6 overloads)]
+
+
+Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ string_view host,
+ string_view service,
+ ResolveHandler && handler);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_resolver::async_resolve (3 of 6 overloads)]
+
+
+Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ ResolveHandler && handler);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload4 ip::basic_resolver::async_resolve (4 of 6 overloads)]
+
+
+Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ ResolveHandler && handler);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload5 ip::basic_resolver::async_resolve (5 of 6 overloads)]
+
+
+Asynchronously perform forward resolution of a query to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ ResolveHandler && handler);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload6 ip::basic_resolver::async_resolve (6 of 6 overloads)]
+
+
+Asynchronously perform reverse resolution of an endpoint to a list of entries.
+
+
+ template<
+ typename ``[link asio.reference.ResolveHandler ResolveHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_resolve(
+ const endpoint_type & e,
+ ResolveHandler && handler);
+
+
+This function is used to asynchronously resolve an endpoint into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][An endpoint object that determines what endpoints will be returned.]]
+
+[[handler][The handler to be called when the resolve operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ resolver::results_type results // Resolved endpoints as a range.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+A successful resolve operation is guaranteed to pass a non-empty range to the handler.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:basic_resolver ip::basic_resolver::basic_resolver]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.basic_resolver..basic_resolver..ip::basic_resolver]
+Constructor.
+
+
+ explicit ``[link asio.reference.ip__basic_resolver.basic_resolver.overload1 basic_resolver]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.basic_resolver.overload1 more...]]``
+
+
+Move-construct a [link asio.reference.ip__basic_resolver `ip::basic_resolver`] from another.
+
+
+ ``[link asio.reference.ip__basic_resolver.basic_resolver.overload2 basic_resolver]``(
+ basic_resolver && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.basic_resolver.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver::basic_resolver (1 of 2 overloads)]
+
+
+Constructor.
+
+
+ basic_resolver(
+ asio::io_context & io_context);
+
+
+This constructor creates a [link asio.reference.ip__basic_resolver `ip::basic_resolver`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the resolver will use to dispatch handlers for any asynchronous operations performed on the resolver. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver::basic_resolver (2 of 2 overloads)]
+
+
+Move-construct a [link asio.reference.ip__basic_resolver `ip::basic_resolver`] from another.
+
+
+ basic_resolver(
+ basic_resolver && other);
+
+
+This constructor moves a resolver from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.ip__basic_resolver `ip::basic_resolver`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_resolver(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:cancel ip::basic_resolver::cancel]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.cancel..cancel..ip::basic_resolver]
+Cancel any asynchronous operations that are waiting on the resolver.
+
+
+ void cancel();
+
+
+This function forces the completion of any pending asynchronous operations on the host resolver. The handler for each cancelled operation will be invoked with the `asio::error::operation_aborted` error code.
+
+
+[endsect]
+
+
+
+[section:canonical_name ip::basic_resolver::canonical_name]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.canonical_name..canonical_name..ip::basic_resolver]
+Determine the canonical name of the host specified in the query.
+
+
+ static const flags canonical_name = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:endpoint_type ip::basic_resolver::endpoint_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.endpoint_type..endpoint_type..ip::basic_resolver]
+The endpoint type.
+
+
+ typedef InternetProtocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:executor_type ip::basic_resolver::executor_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.executor_type..executor_type..ip::basic_resolver]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:flags ip::basic_resolver::flags]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.flags..flags..ip::basic_resolver]
+A bitmask type (C++ Std [lib.bitmask.types]).
+
+
+ typedef unspecified flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor ip::basic_resolver::get_executor]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.get_executor..get_executor..ip::basic_resolver]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context ip::basic_resolver::get_io_context]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.get_io_context..get_io_context..ip::basic_resolver]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service ip::basic_resolver::get_io_service]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.get_io_service..get_io_service..ip::basic_resolver]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:iterator ip::basic_resolver::iterator]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.iterator..iterator..ip::basic_resolver]
+(Deprecated.) The iterator type.
+
+
+ typedef basic_resolver_iterator< InternetProtocol > iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.difference_type [*difference_type]]]
+ [The type used for the distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.reference [*reference]]]
+ [The type of the result of applying operator*() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.value_type [*value_type]]]
+ [The type of the value pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator [*basic_resolver_iterator]]]
+ [Default constructor creates an end iterator.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`] class template is used to define iterators over the results returned by a resolver.
+
+The iterator's value\_type, obtained when the iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:numeric_host ip::basic_resolver::numeric_host]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.numeric_host..numeric_host..ip::basic_resolver]
+Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted.
+
+
+ static const flags numeric_host = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:numeric_service ip::basic_resolver::numeric_service]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.numeric_service..numeric_service..ip::basic_resolver]
+Service name should be treated as a numeric string defining a port number and no name resolution should be attempted.
+
+
+ static const flags numeric_service = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::basic_resolver::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.operator_eq_..operator=..ip::basic_resolver]
+Move-assign a [link asio.reference.ip__basic_resolver `ip::basic_resolver`] from another.
+
+
+ basic_resolver & operator=(
+ basic_resolver && other);
+
+
+This assignment operator moves a resolver from one object to another. Cancels any outstanding asynchronous operations associated with the target object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.ip__basic_resolver `ip::basic_resolver`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `basic_resolver(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:passive ip::basic_resolver::passive]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.passive..passive..ip::basic_resolver]
+Indicate that returned endpoint is intended for use as a locally bound socket endpoint.
+
+
+ static const flags passive = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type ip::basic_resolver::protocol_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.protocol_type..protocol_type..ip::basic_resolver]
+The protocol type.
+
+
+ typedef InternetProtocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:query ip::basic_resolver::query]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.query..query..ip::basic_resolver]
+(Deprecated.) The query type.
+
+
+ typedef basic_resolver_query< InternetProtocol > query;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_query.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_query.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint query. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.basic_resolver_query [*basic_resolver_query]]]
+ [Construct with specified service name for any protocol.
+
+ Construct with specified service name for a given protocol.
+
+ Construct with specified host name and service name for any protocol.
+
+ Construct with specified host name and service name for a given protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.hints [*hints]]]
+ [Get the hints associated with the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.host_name [*host_name]]]
+ [Get the host name associated with the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.service_name [*service_name]]]
+ [Get the service name associated with the query. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_query `ip::basic_resolver_query`] class template describes a query that can be passed to a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:resolve ip::basic_resolver::resolve]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.resolve..resolve..ip::basic_resolver]
+(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload1 resolve]``(
+ const query & q);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload1 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload2 resolve]``(
+ const query & q,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload2 more...]]``
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload3 resolve]``(
+ string_view host,
+ string_view service);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload3 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload4 resolve]``(
+ string_view host,
+ string_view service,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload4 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload5 resolve]``(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload5 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload6 resolve]``(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload6 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload7 resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload7 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload8 resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload8 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload9 resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload9 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload10 resolve]``(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload10 more...]]``
+
+
+Perform reverse resolution of an endpoint to a list of entries.
+
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload11 resolve]``(
+ const endpoint_type & e);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload11 more...]]``
+
+ results_type ``[link asio.reference.ip__basic_resolver.resolve.overload12 resolve]``(
+ const endpoint_type & e,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver.resolve.overload12 more...]]``
+
+
+[section:overload1 ip::basic_resolver::resolve (1 of 12 overloads)]
+
+
+(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const query & q);
+
+
+This function is used to resolve a query into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[q][A query object that determines what endpoints will be returned.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver::resolve (2 of 12 overloads)]
+
+
+(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const query & q,
+ asio::error_code & ec);
+
+
+This function is used to resolve a query into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[q][A query object that determines what endpoints will be returned.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_resolver::resolve (3 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ string_view host,
+ string_view service);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload4 ip::basic_resolver::resolve (4 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ string_view host,
+ string_view service,
+ asio::error_code & ec);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload5 ip::basic_resolver::resolve (5 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload6 ip::basic_resolver::resolve (6 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ asio::error_code & ec);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload7 ip::basic_resolver::resolve (7 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload8 ip::basic_resolver::resolve (8 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ asio::error_code & ec);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload9 ip::basic_resolver::resolve (9 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload10 ip::basic_resolver::resolve (10 of 12 overloads)]
+
+
+Perform forward resolution of a query to a list of entries.
+
+
+ results_type resolve(
+ const protocol_type & protocol,
+ string_view host,
+ string_view service,
+ resolver_base::flags resolve_flags,
+ asio::error_code & ec);
+
+
+This function is used to resolve host and service names into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload11 ip::basic_resolver::resolve (11 of 12 overloads)]
+
+
+Perform reverse resolution of an endpoint to a list of entries.
+
+
+ results_type resolve(
+ const endpoint_type & e);
+
+
+This function is used to resolve an endpoint into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][An endpoint object that determines what endpoints will be returned.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. A successful call to this function is guaranteed to return a non-empty range.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 ip::basic_resolver::resolve (12 of 12 overloads)]
+
+
+Perform reverse resolution of an endpoint to a list of entries.
+
+
+ results_type resolve(
+ const endpoint_type & e,
+ asio::error_code & ec);
+
+
+This function is used to resolve an endpoint into a list of endpoint entries.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][An endpoint object that determines what endpoints will be returned.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+A range object representing the list of endpoint entries. An empty range is returned if an error occurs. A successful call to this function is guaranteed to return a non-empty range.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:results_type ip::basic_resolver::results_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.results_type..results_type..ip::basic_resolver]
+The results type.
+
+
+ typedef basic_resolver_results< InternetProtocol > results_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.const_iterator [*const_iterator]]]
+ [The type of an iterator into the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.const_reference [*const_reference]]]
+ [The type of a const reference to a value in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.difference_type [*difference_type]]]
+ [Type used to represent the distance between two iterators in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the results. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.iterator [*iterator]]]
+ [The type of an iterator into the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.protocol_type [*protocol_type]]]
+ [The protocol type associated with the results. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.reference [*reference]]]
+ [The type of a non-const reference to a value in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.size_type [*size_type]]]
+ [Type used to represent a count of the elements in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.value_type [*value_type]]]
+ [The type of a value in the results range. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.basic_resolver_results [*basic_resolver_results]]]
+ [Default constructor creates an empty range.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.begin [*begin]]]
+ [Obtain a begin iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.cbegin [*cbegin]]]
+ [Obtain a begin iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.cend [*cend]]]
+ [Obtain an end iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.empty [*empty]]]
+ [Determine whether the results range is empty. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.end [*end]]]
+ [Obtain an end iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.max_size [*max_size]]]
+ [Get the maximum number of entries permitted in a results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.size [*size]]]
+ [Get the number of entries in the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.swap [*swap]]]
+ [Swap the results range with another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_results `ip::basic_resolver_results`] class template is used to define a range over the results returned by a resolver.
+
+The iterator's value\_type, obtained when a results iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Remarks]
+
+For backward compatibility, [link asio.reference.ip__basic_resolver_results `ip::basic_resolver_results`] is derived from [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`]. This derivation is deprecated.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:v4_mapped ip::basic_resolver::v4_mapped]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver.v4_mapped..v4_mapped..ip::basic_resolver]
+If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses.
+
+
+ static const flags v4_mapped = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:_basic_resolver ip::basic_resolver::~basic_resolver]
+
+[indexterm2 asio.indexterm.ip__basic_resolver._basic_resolver..~basic_resolver..ip::basic_resolver]
+Destroys the resolver.
+
+
+ ~basic_resolver();
+
+
+This function destroys the resolver, cancelling any outstanding asynchronous wait operations associated with the resolver as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_resolver_entry ip::basic_resolver_entry]
+
+
+An entry produced by a resolver.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_resolver_entry
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_entry.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_resolver_entry ip::basic_resolver_entry::basic_resolver_entry]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.basic_resolver_entry..basic_resolver_entry..ip::basic_resolver_entry]
+Default constructor.
+
+
+ ``[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry.overload1 basic_resolver_entry]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.basic_resolver_entry.overload1 more...]]``
+
+
+Construct with specified endpoint, host name and service name.
+
+
+ ``[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry.overload2 basic_resolver_entry]``(
+ const endpoint_type & ep,
+ string_view host,
+ string_view service);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.basic_resolver_entry.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_entry::basic_resolver_entry (1 of 2 overloads)]
+
+
+Default constructor.
+
+
+ basic_resolver_entry();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_entry::basic_resolver_entry (2 of 2 overloads)]
+
+
+Construct with specified endpoint, host name and service name.
+
+
+ basic_resolver_entry(
+ const endpoint_type & ep,
+ string_view host,
+ string_view service);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:endpoint ip::basic_resolver_entry::endpoint]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.endpoint..endpoint..ip::basic_resolver_entry]
+Get the endpoint associated with the entry.
+
+
+ endpoint_type endpoint() const;
+
+
+
+[endsect]
+
+
+
+[section:endpoint_type ip::basic_resolver_entry::endpoint_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.endpoint_type..endpoint_type..ip::basic_resolver_entry]
+The endpoint type associated with the endpoint entry.
+
+
+ typedef InternetProtocol::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_entry.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:host_name ip::basic_resolver_entry::host_name]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.host_name..host_name..ip::basic_resolver_entry]
+Get the host name associated with the entry.
+
+
+ std::string ``[link asio.reference.ip__basic_resolver_entry.host_name.overload1 host_name]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.host_name.overload1 more...]]``
+
+ template<
+ class Allocator>
+ std::basic_string< char, std::char_traits< char >, Allocator > ``[link asio.reference.ip__basic_resolver_entry.host_name.overload2 host_name]``(
+ const Allocator & alloc = Allocator()) const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.host_name.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_entry::host_name (1 of 2 overloads)]
+
+
+Get the host name associated with the entry.
+
+
+ std::string host_name() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_entry::host_name (2 of 2 overloads)]
+
+
+Get the host name associated with the entry.
+
+
+ template<
+ class Allocator>
+ std::basic_string< char, std::char_traits< char >, Allocator > host_name(
+ const Allocator & alloc = Allocator()) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_endpoint_type ip::basic_resolver_entry::operator endpoint_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.operator_endpoint_type..operator endpoint_type..ip::basic_resolver_entry]
+Convert to the endpoint associated with the entry.
+
+
+ operator endpoint_type() const;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type ip::basic_resolver_entry::protocol_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.protocol_type..protocol_type..ip::basic_resolver_entry]
+The protocol type associated with the endpoint entry.
+
+
+ typedef InternetProtocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_entry.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:service_name ip::basic_resolver_entry::service_name]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_entry.service_name..service_name..ip::basic_resolver_entry]
+Get the service name associated with the entry.
+
+
+ std::string ``[link asio.reference.ip__basic_resolver_entry.service_name.overload1 service_name]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.service_name.overload1 more...]]``
+
+ template<
+ class Allocator>
+ std::basic_string< char, std::char_traits< char >, Allocator > ``[link asio.reference.ip__basic_resolver_entry.service_name.overload2 service_name]``(
+ const Allocator & alloc = Allocator()) const;
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_entry.service_name.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_entry::service_name (1 of 2 overloads)]
+
+
+Get the service name associated with the entry.
+
+
+ std::string service_name() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_entry::service_name (2 of 2 overloads)]
+
+
+Get the service name associated with the entry.
+
+
+ template<
+ class Allocator>
+ std::basic_string< char, std::char_traits< char >, Allocator > service_name(
+ const Allocator & alloc = Allocator()) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:ip__basic_resolver_iterator ip::basic_resolver_iterator]
+
+
+An iterator over the entries produced by a resolver.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_resolver_iterator
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.difference_type [*difference_type]]]
+ [The type used for the distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.reference [*reference]]]
+ [The type of the result of applying operator*() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.value_type [*value_type]]]
+ [The type of the value pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator [*basic_resolver_iterator]]]
+ [Default constructor creates an end iterator.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`] class template is used to define iterators over the results returned by a resolver.
+
+The iterator's value\_type, obtained when the iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_resolver_iterator ip::basic_resolver_iterator::basic_resolver_iterator]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.basic_resolver_iterator..basic_resolver_iterator..ip::basic_resolver_iterator]
+Default constructor creates an end iterator.
+
+
+ ``[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload1 basic_resolver_iterator]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload2 basic_resolver_iterator]``(
+ const basic_resolver_iterator & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload2 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload3 basic_resolver_iterator]``(
+ basic_resolver_iterator && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator.overload3 more...]]``
+
+
+[section:overload1 ip::basic_resolver_iterator::basic_resolver_iterator (1 of 3 overloads)]
+
+
+Default constructor creates an end iterator.
+
+
+ basic_resolver_iterator();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_iterator::basic_resolver_iterator (2 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ basic_resolver_iterator(
+ const basic_resolver_iterator & other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_resolver_iterator::basic_resolver_iterator (3 of 3 overloads)]
+
+
+Move constructor.
+
+
+ basic_resolver_iterator(
+ basic_resolver_iterator && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:dereference ip::basic_resolver_iterator::dereference]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.dereference..dereference..ip::basic_resolver_iterator]
+
+ const basic_resolver_entry< InternetProtocol > & dereference() const;
+
+
+
+[endsect]
+
+
+
+[section:difference_type ip::basic_resolver_iterator::difference_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.difference_type..difference_type..ip::basic_resolver_iterator]
+The type used for the distance between two iterators.
+
+
+ typedef std::ptrdiff_t difference_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:equal ip::basic_resolver_iterator::equal]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.equal..equal..ip::basic_resolver_iterator]
+
+ bool equal(
+ const basic_resolver_iterator & other) const;
+
+
+
+[endsect]
+
+
+
+[section:increment ip::basic_resolver_iterator::increment]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.increment..increment..ip::basic_resolver_iterator]
+
+ void increment();
+
+
+
+[endsect]
+
+
+
+[section:index_ ip::basic_resolver_iterator::index_]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.index_..index_..ip::basic_resolver_iterator]
+
+ std::size_t index_;
+
+
+
+[endsect]
+
+
+
+[section:iterator_category ip::basic_resolver_iterator::iterator_category]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.iterator_category..iterator_category..ip::basic_resolver_iterator]
+The iterator category.
+
+
+ typedef std::forward_iterator_tag iterator_category;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator__star_ ip::basic_resolver_iterator::operator *]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator__star_..operator *..ip::basic_resolver_iterator]
+Dereference an iterator.
+
+
+ const basic_resolver_entry< InternetProtocol > & operator *() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::basic_resolver_iterator::operator!=]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator_not__eq_..operator!=..ip::basic_resolver_iterator]
+Test two iterators for inequality.
+
+
+ friend bool operator!=(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_plus__plus_ ip::basic_resolver_iterator::operator++]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator_plus__plus_..operator++..ip::basic_resolver_iterator]
+Increment operator (prefix).
+
+
+ basic_resolver_iterator & ``[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_.overload1 operator++]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_.overload1 more...]]``
+
+
+Increment operator (postfix).
+
+
+ basic_resolver_iterator ``[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_.overload2 operator++]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_iterator::operator++ (1 of 2 overloads)]
+
+
+Increment operator (prefix).
+
+
+ basic_resolver_iterator & operator++();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_iterator::operator++ (2 of 2 overloads)]
+
+
+Increment operator (postfix).
+
+
+ basic_resolver_iterator operator++(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_arrow_ ip::basic_resolver_iterator::operator->]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator_arrow_..operator->..ip::basic_resolver_iterator]
+Dereference an iterator.
+
+
+ const basic_resolver_entry< InternetProtocol > * operator->() const;
+
+
+
+[endsect]
+
+
+[section:operator_eq_ ip::basic_resolver_iterator::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator_eq_..operator=..ip::basic_resolver_iterator]
+Assignment operator.
+
+
+ basic_resolver_iterator & ``[link asio.reference.ip__basic_resolver_iterator.operator_eq_.overload1 operator=]``(
+ const basic_resolver_iterator & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.operator_eq_.overload1 more...]]``
+
+
+Move-assignment operator.
+
+
+ basic_resolver_iterator & ``[link asio.reference.ip__basic_resolver_iterator.operator_eq_.overload2 operator=]``(
+ basic_resolver_iterator && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_iterator.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_iterator::operator= (1 of 2 overloads)]
+
+
+Assignment operator.
+
+
+ basic_resolver_iterator & operator=(
+ const basic_resolver_iterator & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_iterator::operator= (2 of 2 overloads)]
+
+
+Move-assignment operator.
+
+
+ basic_resolver_iterator & operator=(
+ basic_resolver_iterator && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq__eq_ ip::basic_resolver_iterator::operator==]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.operator_eq__eq_..operator==..ip::basic_resolver_iterator]
+Test two iterators for equality.
+
+
+ friend bool operator==(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:pointer ip::basic_resolver_iterator::pointer]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.pointer..pointer..ip::basic_resolver_iterator]
+The type of the result of applying `operator->()` to the iterator.
+
+
+ typedef const basic_resolver_entry< InternetProtocol > * pointer;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reference ip::basic_resolver_iterator::reference]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.reference..reference..ip::basic_resolver_iterator]
+The type of the result of applying `operator*()` to the iterator.
+
+
+ typedef const basic_resolver_entry< InternetProtocol > & reference;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:value_type ip::basic_resolver_iterator::value_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.value_type..value_type..ip::basic_resolver_iterator]
+The type of the value pointed to by the iterator.
+
+
+ typedef basic_resolver_entry< InternetProtocol > value_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_iterator.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:values_ ip::basic_resolver_iterator::values_]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_iterator.values_..values_..ip::basic_resolver_iterator]
+
+ values_ptr_type values_;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_resolver_query ip::basic_resolver_query]
+
+
+An query to be passed to a resolver.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_resolver_query :
+ public ip::resolver_query_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_query.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_query.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint query. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.basic_resolver_query [*basic_resolver_query]]]
+ [Construct with specified service name for any protocol.
+
+ Construct with specified service name for a given protocol.
+
+ Construct with specified host name and service name for any protocol.
+
+ Construct with specified host name and service name for a given protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.hints [*hints]]]
+ [Get the hints associated with the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.host_name [*host_name]]]
+ [Get the host name associated with the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.service_name [*service_name]]]
+ [Get the service name associated with the query. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_query.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_query `ip::basic_resolver_query`] class template describes a query that can be passed to a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_query.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address_configured ip::basic_resolver_query::address_configured]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.address_configured..address_configured..ip::basic_resolver_query]
+Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system.
+
+
+ static const flags address_configured = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:all_matching ip::basic_resolver_query::all_matching]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.all_matching..all_matching..ip::basic_resolver_query]
+If used with v4\_mapped, return all matching IPv6 and IPv4 addresses.
+
+
+ static const flags all_matching = implementation_defined;
+
+
+
+[endsect]
+
+
+[section:basic_resolver_query ip::basic_resolver_query::basic_resolver_query]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.basic_resolver_query..basic_resolver_query..ip::basic_resolver_query]
+Construct with specified service name for any protocol.
+
+
+ ``[link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload1 basic_resolver_query]``(
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = passive|address_configured);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload1 more...]]``
+
+
+Construct with specified service name for a given protocol.
+
+
+ ``[link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload2 basic_resolver_query]``(
+ const protocol_type & protocol,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = passive|address_configured);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload2 more...]]``
+
+
+Construct with specified host name and service name for any protocol.
+
+
+ ``[link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload3 basic_resolver_query]``(
+ const std::string & host,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = address_configured);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload3 more...]]``
+
+
+Construct with specified host name and service name for a given protocol.
+
+
+ ``[link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload4 basic_resolver_query]``(
+ const protocol_type & protocol,
+ const std::string & host,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = address_configured);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_query.basic_resolver_query.overload4 more...]]``
+
+
+[section:overload1 ip::basic_resolver_query::basic_resolver_query (1 of 4 overloads)]
+
+
+Construct with specified service name for any protocol.
+
+
+ basic_resolver_query(
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = passive|address_configured);
+
+
+This constructor is typically used to perform name resolution for local service binding.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for local service binding.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_query::basic_resolver_query (2 of 4 overloads)]
+
+
+Construct with specified service name for a given protocol.
+
+
+ basic_resolver_query(
+ const protocol_type & protocol,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = passive|address_configured);
+
+
+This constructor is typically used to perform name resolution for local service binding with a specific protocol version.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for local service binding.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_resolver_query::basic_resolver_query (3 of 4 overloads)]
+
+
+Construct with specified host name and service name for any protocol.
+
+
+ basic_resolver_query(
+ const std::string & host,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = address_configured);
+
+
+This constructor is typically used to perform name resolution for communication with remote hosts.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+
+[section:overload4 ip::basic_resolver_query::basic_resolver_query (4 of 4 overloads)]
+
+
+Construct with specified host name and service name for a given protocol.
+
+
+ basic_resolver_query(
+ const protocol_type & protocol,
+ const std::string & host,
+ const std::string & service,
+ resolver_query_base::flags resolve_flags = address_configured);
+
+
+This constructor is typically used to perform name resolution for communication with remote hosts.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[protocol][A protocol object, normally representing either the IPv4 or IPv6 version of an internet protocol.]]
+
+[[host][A string identifying a location. May be a descriptive name or a numeric address string. If an empty string and the passive flag has been specified, the resolved endpoints are suitable for local service binding. If an empty string and passive is not specified, the resolved endpoints will use the loopback address.]]
+
+[[service][A string identifying the requested service. This may be a descriptive name or a numeric string corresponding to a port number. May be an empty string, in which case all resolved endpoints will have a port number of 0.]]
+
+[[resolve_flags][A set of flags that determine how name resolution should be performed. The default flags are suitable for communication with remote hosts.]]
+
+]
+
+
+[heading Remarks]
+
+On POSIX systems, host names may be locally defined in the file `/etc/hosts`. On Windows, host names may be defined in the file `c:\windows\system32\drivers\etc\hosts`. Remote host name resolution is performed using DNS. Operating systems may use additional locations when resolving host names (such as NETBIOS names on Windows).
+
+On POSIX systems, service names are typically defined in the file `/etc/services`. On Windows, service names may be found in the file `c:\windows\system32\drivers\etc\services`. Operating systems may use additional locations when resolving service names.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:canonical_name ip::basic_resolver_query::canonical_name]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.canonical_name..canonical_name..ip::basic_resolver_query]
+Determine the canonical name of the host specified in the query.
+
+
+ static const flags canonical_name = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:flags ip::basic_resolver_query::flags]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.flags..flags..ip::basic_resolver_query]
+A bitmask type (C++ Std [lib.bitmask.types]).
+
+
+ typedef unspecified flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_query.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:hints ip::basic_resolver_query::hints]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.hints..hints..ip::basic_resolver_query]
+Get the hints associated with the query.
+
+
+ const asio::detail::addrinfo_type & hints() const;
+
+
+
+[endsect]
+
+
+
+[section:host_name ip::basic_resolver_query::host_name]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.host_name..host_name..ip::basic_resolver_query]
+Get the host name associated with the query.
+
+
+ std::string host_name() const;
+
+
+
+[endsect]
+
+
+
+[section:numeric_host ip::basic_resolver_query::numeric_host]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.numeric_host..numeric_host..ip::basic_resolver_query]
+Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted.
+
+
+ static const flags numeric_host = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:numeric_service ip::basic_resolver_query::numeric_service]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.numeric_service..numeric_service..ip::basic_resolver_query]
+Service name should be treated as a numeric string defining a port number and no name resolution should be attempted.
+
+
+ static const flags numeric_service = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:passive ip::basic_resolver_query::passive]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.passive..passive..ip::basic_resolver_query]
+Indicate that returned endpoint is intended for use as a locally bound socket endpoint.
+
+
+ static const flags passive = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type ip::basic_resolver_query::protocol_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.protocol_type..protocol_type..ip::basic_resolver_query]
+The protocol type associated with the endpoint query.
+
+
+ typedef InternetProtocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_query.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:service_name ip::basic_resolver_query::service_name]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.service_name..service_name..ip::basic_resolver_query]
+Get the service name associated with the query.
+
+
+ std::string service_name() const;
+
+
+
+[endsect]
+
+
+
+[section:v4_mapped ip::basic_resolver_query::v4_mapped]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_query.v4_mapped..v4_mapped..ip::basic_resolver_query]
+If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses.
+
+
+ static const flags v4_mapped = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__basic_resolver_results ip::basic_resolver_results]
+
+
+A range of entries produced by a resolver.
+
+
+ template<
+ typename ``[link asio.reference.InternetProtocol InternetProtocol]``>
+ class basic_resolver_results :
+ public ip::basic_resolver_iterator< InternetProtocol >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.const_iterator [*const_iterator]]]
+ [The type of an iterator into the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.const_reference [*const_reference]]]
+ [The type of a const reference to a value in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.difference_type [*difference_type]]]
+ [Type used to represent the distance between two iterators in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the results. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.iterator [*iterator]]]
+ [The type of an iterator into the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.protocol_type [*protocol_type]]]
+ [The protocol type associated with the results. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.reference [*reference]]]
+ [The type of a non-const reference to a value in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.size_type [*size_type]]]
+ [Type used to represent a count of the elements in the range. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_results.value_type [*value_type]]]
+ [The type of a value in the results range. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.basic_resolver_results [*basic_resolver_results]]]
+ [Default constructor creates an empty range.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.begin [*begin]]]
+ [Obtain a begin iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.cbegin [*cbegin]]]
+ [Obtain a begin iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.cend [*cend]]]
+ [Obtain an end iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.empty [*empty]]]
+ [Determine whether the results range is empty. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.end [*end]]]
+ [Obtain an end iterator for the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.max_size [*max_size]]]
+ [Get the maximum number of entries permitted in a results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.size [*size]]]
+ [Get the number of entries in the results range. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.swap [*swap]]]
+ [Swap the results range with another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_results.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_results `ip::basic_resolver_results`] class template is used to define a range over the results returned by a resolver.
+
+The iterator's value\_type, obtained when a results iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Remarks]
+
+For backward compatibility, [link asio.reference.ip__basic_resolver_results `ip::basic_resolver_results`] is derived from [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`]. This derivation is deprecated.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_resolver_results ip::basic_resolver_results::basic_resolver_results]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.basic_resolver_results..basic_resolver_results..ip::basic_resolver_results]
+Default constructor creates an empty range.
+
+
+ ``[link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload1 basic_resolver_results]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload1 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload2 basic_resolver_results]``(
+ const basic_resolver_results & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload2 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload3 basic_resolver_results]``(
+ basic_resolver_results && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.basic_resolver_results.overload3 more...]]``
+
+
+[section:overload1 ip::basic_resolver_results::basic_resolver_results (1 of 3 overloads)]
+
+
+Default constructor creates an empty range.
+
+
+ basic_resolver_results();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_results::basic_resolver_results (2 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ basic_resolver_results(
+ const basic_resolver_results & other);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::basic_resolver_results::basic_resolver_results (3 of 3 overloads)]
+
+
+Move constructor.
+
+
+ basic_resolver_results(
+ basic_resolver_results && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:begin ip::basic_resolver_results::begin]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.begin..begin..ip::basic_resolver_results]
+Obtain a begin iterator for the results range.
+
+
+ const_iterator begin() const;
+
+
+
+[endsect]
+
+
+
+[section:cbegin ip::basic_resolver_results::cbegin]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.cbegin..cbegin..ip::basic_resolver_results]
+Obtain a begin iterator for the results range.
+
+
+ const_iterator cbegin() const;
+
+
+
+[endsect]
+
+
+
+[section:cend ip::basic_resolver_results::cend]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.cend..cend..ip::basic_resolver_results]
+Obtain an end iterator for the results range.
+
+
+ const_iterator cend() const;
+
+
+
+[endsect]
+
+
+
+[section:const_iterator ip::basic_resolver_results::const_iterator]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.const_iterator..const_iterator..ip::basic_resolver_results]
+The type of an iterator into the range.
+
+
+ typedef basic_resolver_iterator< protocol_type > const_iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.difference_type [*difference_type]]]
+ [The type used for the distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.reference [*reference]]]
+ [The type of the result of applying operator*() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.value_type [*value_type]]]
+ [The type of the value pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator [*basic_resolver_iterator]]]
+ [Default constructor creates an end iterator.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`] class template is used to define iterators over the results returned by a resolver.
+
+The iterator's value\_type, obtained when the iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:const_reference ip::basic_resolver_results::const_reference]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.const_reference..const_reference..ip::basic_resolver_results]
+The type of a const reference to a value in the range.
+
+
+ typedef const value_type & const_reference;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:dereference ip::basic_resolver_results::dereference]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.dereference..dereference..ip::basic_resolver_results]
+
+ const basic_resolver_entry< InternetProtocol > & dereference() const;
+
+
+
+[endsect]
+
+
+
+[section:difference_type ip::basic_resolver_results::difference_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.difference_type..difference_type..ip::basic_resolver_results]
+Type used to represent the distance between two iterators in the range.
+
+
+ typedef std::ptrdiff_t difference_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:empty ip::basic_resolver_results::empty]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.empty..empty..ip::basic_resolver_results]
+Determine whether the results range is empty.
+
+
+ bool empty() const;
+
+
+
+[endsect]
+
+
+
+[section:end ip::basic_resolver_results::end]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.end..end..ip::basic_resolver_results]
+Obtain an end iterator for the results range.
+
+
+ const_iterator end() const;
+
+
+
+[endsect]
+
+
+
+[section:endpoint_type ip::basic_resolver_results::endpoint_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.endpoint_type..endpoint_type..ip::basic_resolver_results]
+The endpoint type associated with the results.
+
+
+ typedef protocol_type::endpoint endpoint_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:equal ip::basic_resolver_results::equal]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.equal..equal..ip::basic_resolver_results]
+
+ bool equal(
+ const basic_resolver_iterator & other) const;
+
+
+
+[endsect]
+
+
+
+[section:increment ip::basic_resolver_results::increment]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.increment..increment..ip::basic_resolver_results]
+
+ void increment();
+
+
+
+[endsect]
+
+
+
+[section:index_ ip::basic_resolver_results::index_]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.index_..index_..ip::basic_resolver_results]
+
+ std::size_t index_;
+
+
+
+[endsect]
+
+
+
+[section:iterator ip::basic_resolver_results::iterator]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.iterator..iterator..ip::basic_resolver_results]
+The type of an iterator into the range.
+
+
+ typedef const_iterator iterator;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.difference_type [*difference_type]]]
+ [The type used for the distance between two iterators. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.iterator_category [*iterator_category]]]
+ [The iterator category. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.pointer [*pointer]]]
+ [The type of the result of applying operator->() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.reference [*reference]]]
+ [The type of the result of applying operator*() to the iterator. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_iterator.value_type [*value_type]]]
+ [The type of the value pointed to by the iterator. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.basic_resolver_iterator [*basic_resolver_iterator]]]
+ [Default constructor creates an end iterator.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator__star_ [*operator *]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_plus__plus_ [*operator++]]]
+ [Increment operator (prefix).
+
+ Increment operator (postfix). ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_arrow_ [*operator->]]]
+ [Dereference an iterator. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Move-assignment operator. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.dereference [*dereference]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.equal [*equal]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.increment [*increment]]]
+ []
+ ]
+
+]
+
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.index_ [*index_]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.values_ [*values_]]]
+ []
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_not__eq_ [*operator!=]]]
+ [Test two iterators for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_iterator.operator_eq__eq_ [*operator==]]]
+ [Test two iterators for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_iterator `ip::basic_resolver_iterator`] class template is used to define iterators over the results returned by a resolver.
+
+The iterator's value\_type, obtained when the iterator is dereferenced, is:
+
+ const basic_resolver_entry<InternetProtocol>
+
+
+
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:iterator_category ip::basic_resolver_results::iterator_category]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.iterator_category..iterator_category..ip::basic_resolver_results]
+The iterator category.
+
+
+ typedef std::forward_iterator_tag iterator_category;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_size ip::basic_resolver_results::max_size]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.max_size..max_size..ip::basic_resolver_results]
+Get the maximum number of entries permitted in a results range.
+
+
+ size_type max_size() const;
+
+
+
+[endsect]
+
+
+
+[section:operator__star_ ip::basic_resolver_results::operator *]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator__star_..operator *..ip::basic_resolver_results]
+Dereference an iterator.
+
+
+ const basic_resolver_entry< InternetProtocol > & operator *() const;
+
+
+
+[endsect]
+
+
+[section:operator_not__eq_ ip::basic_resolver_results::operator!=]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator_not__eq_..operator!=..ip::basic_resolver_results]
+Test two iterators for inequality.
+
+
+ friend bool ``[link asio.reference.ip__basic_resolver_results.operator_not__eq_.overload1 operator!=]``(
+ const basic_resolver_results & a,
+ const basic_resolver_results & b);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_not__eq_.overload1 more...]]``
+
+ friend bool ``[link asio.reference.ip__basic_resolver_results.operator_not__eq_.overload2 operator!=]``(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_not__eq_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_results::operator!= (1 of 2 overloads)]
+
+
+Test two iterators for inequality.
+
+
+ friend bool operator!=(
+ const basic_resolver_results & a,
+ const basic_resolver_results & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_results::operator!= (2 of 2 overloads)]
+
+
+['Inherited from ip::basic_resolver.]
+
+
+Test two iterators for inequality.
+
+
+ friend bool operator!=(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_plus__plus_ ip::basic_resolver_results::operator++]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator_plus__plus_..operator++..ip::basic_resolver_results]
+Increment operator (prefix).
+
+
+ basic_resolver_iterator & ``[link asio.reference.ip__basic_resolver_results.operator_plus__plus_.overload1 operator++]``();
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_plus__plus_.overload1 more...]]``
+
+
+Increment operator (postfix).
+
+
+ basic_resolver_iterator ``[link asio.reference.ip__basic_resolver_results.operator_plus__plus_.overload2 operator++]``(
+ int );
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_plus__plus_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_results::operator++ (1 of 2 overloads)]
+
+
+['Inherited from ip::basic_resolver.]
+
+
+Increment operator (prefix).
+
+
+ basic_resolver_iterator & operator++();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_results::operator++ (2 of 2 overloads)]
+
+
+['Inherited from ip::basic_resolver.]
+
+
+Increment operator (postfix).
+
+
+ basic_resolver_iterator operator++(
+ int );
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_arrow_ ip::basic_resolver_results::operator->]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator_arrow_..operator->..ip::basic_resolver_results]
+Dereference an iterator.
+
+
+ const basic_resolver_entry< InternetProtocol > * operator->() const;
+
+
+
+[endsect]
+
+
+[section:operator_eq_ ip::basic_resolver_results::operator=]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator_eq_..operator=..ip::basic_resolver_results]
+Assignment operator.
+
+
+ basic_resolver_results & ``[link asio.reference.ip__basic_resolver_results.operator_eq_.overload1 operator=]``(
+ const basic_resolver_results & other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_eq_.overload1 more...]]``
+
+
+Move-assignment operator.
+
+
+ basic_resolver_results & ``[link asio.reference.ip__basic_resolver_results.operator_eq_.overload2 operator=]``(
+ basic_resolver_results && other);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_eq_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_results::operator= (1 of 2 overloads)]
+
+
+Assignment operator.
+
+
+ basic_resolver_results & operator=(
+ const basic_resolver_results & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_results::operator= (2 of 2 overloads)]
+
+
+Move-assignment operator.
+
+
+ basic_resolver_results & operator=(
+ basic_resolver_results && other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_eq__eq_ ip::basic_resolver_results::operator==]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.operator_eq__eq_..operator==..ip::basic_resolver_results]
+Test two iterators for equality.
+
+
+ friend bool ``[link asio.reference.ip__basic_resolver_results.operator_eq__eq_.overload1 operator==]``(
+ const basic_resolver_results & a,
+ const basic_resolver_results & b);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_eq__eq_.overload1 more...]]``
+
+ friend bool ``[link asio.reference.ip__basic_resolver_results.operator_eq__eq_.overload2 operator==]``(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+ `` [''''&raquo;''' [link asio.reference.ip__basic_resolver_results.operator_eq__eq_.overload2 more...]]``
+
+
+[section:overload1 ip::basic_resolver_results::operator== (1 of 2 overloads)]
+
+
+Test two iterators for equality.
+
+
+ friend bool operator==(
+ const basic_resolver_results & a,
+ const basic_resolver_results & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 ip::basic_resolver_results::operator== (2 of 2 overloads)]
+
+
+['Inherited from ip::basic_resolver.]
+
+
+Test two iterators for equality.
+
+
+ friend bool operator==(
+ const basic_resolver_iterator & a,
+ const basic_resolver_iterator & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:pointer ip::basic_resolver_results::pointer]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.pointer..pointer..ip::basic_resolver_results]
+The type of the result of applying `operator->()` to the iterator.
+
+
+ typedef const basic_resolver_entry< InternetProtocol > * pointer;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol_type ip::basic_resolver_results::protocol_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.protocol_type..protocol_type..ip::basic_resolver_results]
+The protocol type associated with the results.
+
+
+ typedef InternetProtocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reference ip::basic_resolver_results::reference]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.reference..reference..ip::basic_resolver_results]
+The type of a non-const reference to a value in the range.
+
+
+ typedef value_type & reference;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:size ip::basic_resolver_results::size]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.size..size..ip::basic_resolver_results]
+Get the number of entries in the results range.
+
+
+ size_type size() const;
+
+
+
+[endsect]
+
+
+
+[section:size_type ip::basic_resolver_results::size_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.size_type..size_type..ip::basic_resolver_results]
+Type used to represent a count of the elements in the range.
+
+
+ typedef std::size_t size_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:swap ip::basic_resolver_results::swap]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.swap..swap..ip::basic_resolver_results]
+Swap the results range with another.
+
+
+ void swap(
+ basic_resolver_results & that);
+
+
+
+[endsect]
+
+
+
+[section:value_type ip::basic_resolver_results::value_type]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.value_type..value_type..ip::basic_resolver_results]
+The type of a value in the results range.
+
+
+ typedef basic_resolver_entry< endpoint_type > value_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.endpoint_type [*endpoint_type]]]
+ [The endpoint type associated with the endpoint entry. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver_entry.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint entry. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.basic_resolver_entry [*basic_resolver_entry]]]
+ [Default constructor.
+
+ Construct with specified endpoint, host name and service name. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.endpoint [*endpoint]]]
+ [Get the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.host_name [*host_name]]]
+ [Get the host name associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.operator_endpoint_type [*operator endpoint_type]]]
+ [Convert to the endpoint associated with the entry. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver_entry.service_name [*service_name]]]
+ [Get the service name associated with the entry. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver_entry `ip::basic_resolver_entry`] class template describes an entry as returned by a resolver.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/basic_resolver_results.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:values_ ip::basic_resolver_results::values_]
+
+
+['Inherited from ip::basic_resolver.]
+
+[indexterm2 asio.indexterm.ip__basic_resolver_results.values_..values_..ip::basic_resolver_results]
+
+ values_ptr_type values_;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__host_name ip::host_name]
+
+[indexterm1 asio.indexterm.ip__host_name..ip::host_name]
+Get the current host name.
+
+
+ std::string ``[link asio.reference.ip__host_name.overload1 host_name]``();
+ `` [''''&raquo;''' [link asio.reference.ip__host_name.overload1 more...]]``
+
+ std::string ``[link asio.reference.ip__host_name.overload2 host_name]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__host_name.overload2 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/ip/host_name.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 ip::host_name (1 of 2 overloads)]
+
+
+Get the current host name.
+
+
+ std::string host_name();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::host_name (2 of 2 overloads)]
+
+
+Get the current host name.
+
+
+ std::string host_name(
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:ip__icmp ip::icmp]
+
+
+Encapsulates the flags needed for ICMP.
+
+
+ class icmp
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__icmp.endpoint [*endpoint]]]
+ [The type of a ICMP endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__icmp.resolver [*resolver]]]
+ [The ICMP resolver type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__icmp.socket [*socket]]]
+ [The ICMP socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__icmp.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.ip__icmp.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__icmp.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__icmp.v4 [*v4]]]
+ [Construct to represent the IPv4 ICMP protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__icmp.v6 [*v6]]]
+ [Construct to represent the IPv6 ICMP protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__icmp.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__icmp.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__icmp `ip::icmp`] class contains flags necessary for ICMP sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint ip::icmp::endpoint]
+
+[indexterm2 asio.indexterm.ip__icmp.endpoint..endpoint..ip::icmp]
+The type of a ICMP endpoint.
+
+
+ typedef basic_endpoint< icmp > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.address [*address]]]
+ [Get the IP address associated with the endpoint.
+
+ Set the IP address associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR_ANY or in6addr_any). This constructor would typically be used for accepting new connections.
+
+ Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint.
+
+ Move-assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.port [*port]]]
+ [Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+ Set the port associated with the endpoint. The port number is always in the host's byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_endpoint `ip::basic_endpoint`] class template describes an endpoint that may be associated with a particular socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family ip::icmp::family]
+
+[indexterm2 asio.indexterm.ip__icmp.family..family..ip::icmp]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::icmp::operator!=]
+
+[indexterm2 asio.indexterm.ip__icmp.operator_not__eq_..operator!=..ip::icmp]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const icmp & p1,
+ const icmp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::icmp::operator==]
+
+[indexterm2 asio.indexterm.ip__icmp.operator_eq__eq_..operator==..ip::icmp]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const icmp & p1,
+ const icmp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol ip::icmp::protocol]
+
+[indexterm2 asio.indexterm.ip__icmp.protocol..protocol..ip::icmp]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:resolver ip::icmp::resolver]
+
+[indexterm2 asio.indexterm.ip__icmp.resolver..resolver..ip::icmp]
+The ICMP resolver type.
+
+
+ typedef basic_resolver< icmp > resolver;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.iterator [*iterator]]]
+ [(Deprecated.) The iterator type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.query [*query]]]
+ [(Deprecated.) The query type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.results_type [*results_type]]]
+ [The results type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.async_resolve [*async_resolve]]]
+ [(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.basic_resolver [*basic_resolver]]]
+ [Constructor.
+
+ Move-construct a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the resolver. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.operator_eq_ [*operator=]]]
+ [Move-assign a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.resolve [*resolve]]]
+ [(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+ Perform forward resolution of a query to a list of entries.
+
+ Perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver._basic_resolver [*~basic_resolver]]]
+ [Destroys the resolver. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver `ip::basic_resolver`] class template provides the ability to resolve a query to a list of endpoints.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:socket ip::icmp::socket]
+
+[indexterm2 asio.indexterm.ip__icmp.socket..socket..ip::icmp]
+The ICMP socket type.
+
+
+ typedef basic_raw_socket< icmp > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_raw_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.basic_raw_socket [*basic_raw_socket]]]
+ [Construct a basic_raw_socket without opening it.
+
+ Construct and open a basic_raw_socket.
+
+ Construct a basic_raw_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_raw_socket on an existing native socket.
+
+ Move-construct a basic_raw_socket from another.
+
+ Move-construct a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_raw_socket from another.
+
+ Move-assign a basic_raw_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.receive_from [*receive_from]]]
+ [Receive raw data with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.send_to [*send_to]]]
+ [Send raw data to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket._basic_raw_socket [*~basic_raw_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_raw_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_raw_socket `basic_raw_socket`] class template provides asynchronous and blocking raw-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/icmp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type ip::icmp::type]
+
+[indexterm2 asio.indexterm.ip__icmp.type..type..ip::icmp]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[section:v4 ip::icmp::v4]
+
+[indexterm2 asio.indexterm.ip__icmp.v4..v4..ip::icmp]
+Construct to represent the IPv4 ICMP protocol.
+
+
+ static icmp v4();
+
+
+
+[endsect]
+
+
+
+[section:v6 ip::icmp::v6]
+
+[indexterm2 asio.indexterm.ip__icmp.v6..v6..ip::icmp]
+Construct to represent the IPv6 ICMP protocol.
+
+
+ static icmp v6();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ip__multicast__enable_loopback ip::multicast::enable_loopback]
+
+[indexterm1 asio.indexterm.ip__multicast__enable_loopback..ip::multicast::enable_loopback]
+Socket option determining whether outgoing multicast packets will be received on the same socket if it is a member of the multicast group.
+
+
+ typedef implementation_defined enable_loopback;
+
+
+
+Implements the IPPROTO\_IP/IP\_MULTICAST\_LOOP socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::multicast::enable_loopback option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::multicast::enable_loopback option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/multicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__multicast__hops ip::multicast::hops]
+
+[indexterm1 asio.indexterm.ip__multicast__hops..ip::multicast::hops]
+Socket option for time-to-live associated with outgoing multicast packets.
+
+
+ typedef implementation_defined hops;
+
+
+
+Implements the IPPROTO\_IP/IP\_MULTICAST\_TTL socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::multicast::hops option(4);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::multicast::hops option;
+ socket.get_option(option);
+ int ttl = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/multicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__multicast__join_group ip::multicast::join_group]
+
+[indexterm1 asio.indexterm.ip__multicast__join_group..ip::multicast::join_group]
+Socket option to join a multicast group on a specified interface.
+
+
+ typedef implementation_defined join_group;
+
+
+
+Implements the IPPROTO\_IP/IP\_ADD\_MEMBERSHIP socket option.
+
+
+[heading Examples]
+
+Setting the option to join a multicast group:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::address multicast_address =
+ asio::ip::address::from_string("225.0.0.1");
+ asio::ip::multicast::join_group option(multicast_address);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/multicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__multicast__leave_group ip::multicast::leave_group]
+
+[indexterm1 asio.indexterm.ip__multicast__leave_group..ip::multicast::leave_group]
+Socket option to leave a multicast group on a specified interface.
+
+
+ typedef implementation_defined leave_group;
+
+
+
+Implements the IPPROTO\_IP/IP\_DROP\_MEMBERSHIP socket option.
+
+
+[heading Examples]
+
+Setting the option to leave a multicast group:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::address multicast_address =
+ asio::ip::address::from_string("225.0.0.1");
+ asio::ip::multicast::leave_group option(multicast_address);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/multicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__multicast__outbound_interface ip::multicast::outbound_interface]
+
+[indexterm1 asio.indexterm.ip__multicast__outbound_interface..ip::multicast::outbound_interface]
+Socket option for local interface to use for outgoing multicast packets.
+
+
+ typedef implementation_defined outbound_interface;
+
+
+
+Implements the IPPROTO\_IP/IP\_MULTICAST\_IF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::address_v4 local_interface =
+ asio::ip::address_v4::from_string("1.2.3.4");
+ asio::ip::multicast::outbound_interface option(local_interface);
+ socket.set_option(option);
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/multicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:ip__network_v4 ip::network_v4]
+
+
+Represents an IPv4 network.
+
+
+ class network_v4
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v4.address [*address]]]
+ [Obtain the address object specified when the network object was created. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.broadcast [*broadcast]]]
+ [Obtain an address object that represents the network's broadcast address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.canonical [*canonical]]]
+ [Obtain the true network address, omitting any host bits. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.hosts [*hosts]]]
+ [Obtain an address range corresponding to the hosts in the network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.is_host [*is_host]]]
+ [Test if network is a valid host address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.is_subnet_of [*is_subnet_of]]]
+ [Test if a network is a real subnet of another network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.netmask [*netmask]]]
+ [Obtain the netmask that was specified when the network object was created. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.network [*network]]]
+ [Obtain an address object that represents the network address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.network_v4 [*network_v4]]]
+ [Default constructor.
+
+ Construct a network based on the specified address and prefix length.
+
+ Construct network based on the specified address and netmask.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.operator_eq_ [*operator=]]]
+ [Assign from another network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.prefix_length [*prefix_length]]]
+ [Obtain the prefix length that was specified when the network object was created. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.to_string [*to_string]]]
+ [Get the network as an address in dotted decimal format. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v4.operator_not__eq_ [*operator!=]]]
+ [Compare two networks for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v4.operator_eq__eq_ [*operator==]]]
+ [Compare two networks for equality. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v4.make_network_v4 [*make_network_v4]]]
+ [Create an IPv4 network from a string containing IP address and prefix length. ]
+ ]
+
+]
+
+The [link asio.reference.ip__network_v4 `ip::network_v4`] class provides the ability to use and manipulate IP version 4 networks.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address ip::network_v4::address]
+
+[indexterm2 asio.indexterm.ip__network_v4.address..address..ip::network_v4]
+Obtain the address object specified when the network object was created.
+
+
+ address_v4 address() const;
+
+
+
+[endsect]
+
+
+
+[section:broadcast ip::network_v4::broadcast]
+
+[indexterm2 asio.indexterm.ip__network_v4.broadcast..broadcast..ip::network_v4]
+Obtain an address object that represents the network's broadcast address.
+
+
+ address_v4 broadcast() const;
+
+
+
+[endsect]
+
+
+
+[section:canonical ip::network_v4::canonical]
+
+[indexterm2 asio.indexterm.ip__network_v4.canonical..canonical..ip::network_v4]
+Obtain the true network address, omitting any host bits.
+
+
+ network_v4 canonical() const;
+
+
+
+[endsect]
+
+
+
+[section:hosts ip::network_v4::hosts]
+
+[indexterm2 asio.indexterm.ip__network_v4.hosts..hosts..ip::network_v4]
+Obtain an address range corresponding to the hosts in the network.
+
+
+ address_v4_range hosts() const;
+
+
+
+[endsect]
+
+
+
+[section:is_host ip::network_v4::is_host]
+
+[indexterm2 asio.indexterm.ip__network_v4.is_host..is_host..ip::network_v4]
+Test if network is a valid host address.
+
+
+ bool is_host() const;
+
+
+
+[endsect]
+
+
+
+[section:is_subnet_of ip::network_v4::is_subnet_of]
+
+[indexterm2 asio.indexterm.ip__network_v4.is_subnet_of..is_subnet_of..ip::network_v4]
+Test if a network is a real subnet of another network.
+
+
+ bool is_subnet_of(
+ const network_v4 & other) const;
+
+
+
+[endsect]
+
+
+[section:make_network_v4 ip::network_v4::make_network_v4]
+
+[indexterm2 asio.indexterm.ip__network_v4.make_network_v4..make_network_v4..ip::network_v4]
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload1 make_network_v4]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload1 more...]]``
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload2 make_network_v4]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload2 more...]]``
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload3 make_network_v4]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload3 more...]]``
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload4 make_network_v4]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload4 more...]]``
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload5 make_network_v4]``(
+ string_view str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload5 more...]]``
+
+ network_v4 ``[link asio.reference.ip__network_v4.make_network_v4.overload6 make_network_v4]``(
+ string_view str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.make_network_v4.overload6 more...]]``
+
+
+[section:overload1 ip::network_v4::make_network_v4 (1 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v4::make_network_v4 (2 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::network_v4::make_network_v4 (3 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::network_v4::make_network_v4 (4 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::network_v4::make_network_v4 (5 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ string_view str);
+
+
+
+[endsect]
+
+
+
+[section:overload6 ip::network_v4::make_network_v4 (6 of 6 overloads)]
+
+
+Create an IPv4 network from a string containing IP address and prefix length.
+
+
+ network_v4 make_network_v4(
+ string_view str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:netmask ip::network_v4::netmask]
+
+[indexterm2 asio.indexterm.ip__network_v4.netmask..netmask..ip::network_v4]
+Obtain the netmask that was specified when the network object was created.
+
+
+ address_v4 netmask() const;
+
+
+
+[endsect]
+
+
+
+[section:network ip::network_v4::network]
+
+[indexterm2 asio.indexterm.ip__network_v4.network..network..ip::network_v4]
+Obtain an address object that represents the network address.
+
+
+ address_v4 network() const;
+
+
+
+[endsect]
+
+
+[section:network_v4 ip::network_v4::network_v4]
+
+[indexterm2 asio.indexterm.ip__network_v4.network_v4..network_v4..ip::network_v4]
+Default constructor.
+
+
+ ``[link asio.reference.ip__network_v4.network_v4.overload1 network_v4]``();
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.network_v4.overload1 more...]]``
+
+
+Construct a network based on the specified address and prefix length.
+
+
+ ``[link asio.reference.ip__network_v4.network_v4.overload2 network_v4]``(
+ const address_v4 & addr,
+ unsigned short prefix_len);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.network_v4.overload2 more...]]``
+
+
+Construct network based on the specified address and netmask.
+
+
+ ``[link asio.reference.ip__network_v4.network_v4.overload3 network_v4]``(
+ const address_v4 & addr,
+ const address_v4 & mask);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.network_v4.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__network_v4.network_v4.overload4 network_v4]``(
+ const network_v4 & other);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.network_v4.overload4 more...]]``
+
+
+[section:overload1 ip::network_v4::network_v4 (1 of 4 overloads)]
+
+
+Default constructor.
+
+
+ network_v4();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v4::network_v4 (2 of 4 overloads)]
+
+
+Construct a network based on the specified address and prefix length.
+
+
+ network_v4(
+ const address_v4 & addr,
+ unsigned short prefix_len);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::network_v4::network_v4 (3 of 4 overloads)]
+
+
+Construct network based on the specified address and netmask.
+
+
+ network_v4(
+ const address_v4 & addr,
+ const address_v4 & mask);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::network_v4::network_v4 (4 of 4 overloads)]
+
+
+Copy constructor.
+
+
+ network_v4(
+ const network_v4 & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_not__eq_ ip::network_v4::operator!=]
+
+[indexterm2 asio.indexterm.ip__network_v4.operator_not__eq_..operator!=..ip::network_v4]
+Compare two networks for inequality.
+
+
+ friend bool operator!=(
+ const network_v4 & a,
+ const network_v4 & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::network_v4::operator=]
+
+[indexterm2 asio.indexterm.ip__network_v4.operator_eq_..operator=..ip::network_v4]
+Assign from another network.
+
+
+ network_v4 & operator=(
+ const network_v4 & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::network_v4::operator==]
+
+[indexterm2 asio.indexterm.ip__network_v4.operator_eq__eq_..operator==..ip::network_v4]
+Compare two networks for equality.
+
+
+ friend bool operator==(
+ const network_v4 & a,
+ const network_v4 & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v4.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:prefix_length ip::network_v4::prefix_length]
+
+[indexterm2 asio.indexterm.ip__network_v4.prefix_length..prefix_length..ip::network_v4]
+Obtain the prefix length that was specified when the network object was created.
+
+
+ unsigned short prefix_length() const;
+
+
+
+[endsect]
+
+
+[section:to_string ip::network_v4::to_string]
+
+[indexterm2 asio.indexterm.ip__network_v4.to_string..to_string..ip::network_v4]
+Get the network as an address in dotted decimal format.
+
+
+ std::string ``[link asio.reference.ip__network_v4.to_string.overload1 to_string]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.to_string.overload1 more...]]``
+
+ std::string ``[link asio.reference.ip__network_v4.to_string.overload2 to_string]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.ip__network_v4.to_string.overload2 more...]]``
+
+
+[section:overload1 ip::network_v4::to_string (1 of 2 overloads)]
+
+
+Get the network as an address in dotted decimal format.
+
+
+ std::string to_string() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v4::to_string (2 of 2 overloads)]
+
+
+Get the network as an address in dotted decimal format.
+
+
+ std::string to_string(
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:ip__network_v6 ip::network_v6]
+
+
+Represents an IPv6 network.
+
+
+ class network_v6
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v6.address [*address]]]
+ [Obtain the address object specified when the network object was created. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.canonical [*canonical]]]
+ [Obtain the true network address, omitting any host bits. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.hosts [*hosts]]]
+ [Obtain an address range corresponding to the hosts in the network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.is_host [*is_host]]]
+ [Test if network is a valid host address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.is_subnet_of [*is_subnet_of]]]
+ [Test if a network is a real subnet of another network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.network [*network]]]
+ [Obtain an address object that represents the network address. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.network_v6 [*network_v6]]]
+ [Default constructor.
+
+ Construct a network based on the specified address and prefix length.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.operator_eq_ [*operator=]]]
+ [Assign from another network. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.prefix_length [*prefix_length]]]
+ [Obtain the prefix length that was specified when the network object was created. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.to_string [*to_string]]]
+ [Get the network as an address in dotted decimal format. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v6.operator_not__eq_ [*operator!=]]]
+ [Compare two networks for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__network_v6.operator_eq__eq_ [*operator==]]]
+ [Compare two networks for equality. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__network_v6.make_network_v6 [*make_network_v6]]]
+ [Create an IPv6 network from a string containing IP address and prefix length. ]
+ ]
+
+]
+
+The [link asio.reference.ip__network_v6 `ip::network_v6`] class provides the ability to use and manipulate IP version 6 networks.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address ip::network_v6::address]
+
+[indexterm2 asio.indexterm.ip__network_v6.address..address..ip::network_v6]
+Obtain the address object specified when the network object was created.
+
+
+ address_v6 address() const;
+
+
+
+[endsect]
+
+
+
+[section:canonical ip::network_v6::canonical]
+
+[indexterm2 asio.indexterm.ip__network_v6.canonical..canonical..ip::network_v6]
+Obtain the true network address, omitting any host bits.
+
+
+ network_v6 canonical() const;
+
+
+
+[endsect]
+
+
+
+[section:hosts ip::network_v6::hosts]
+
+[indexterm2 asio.indexterm.ip__network_v6.hosts..hosts..ip::network_v6]
+Obtain an address range corresponding to the hosts in the network.
+
+
+ address_v6_range hosts() const;
+
+
+
+[endsect]
+
+
+
+[section:is_host ip::network_v6::is_host]
+
+[indexterm2 asio.indexterm.ip__network_v6.is_host..is_host..ip::network_v6]
+Test if network is a valid host address.
+
+
+ bool is_host() const;
+
+
+
+[endsect]
+
+
+
+[section:is_subnet_of ip::network_v6::is_subnet_of]
+
+[indexterm2 asio.indexterm.ip__network_v6.is_subnet_of..is_subnet_of..ip::network_v6]
+Test if a network is a real subnet of another network.
+
+
+ bool is_subnet_of(
+ const network_v6 & other) const;
+
+
+
+[endsect]
+
+
+[section:make_network_v6 ip::network_v6::make_network_v6]
+
+[indexterm2 asio.indexterm.ip__network_v6.make_network_v6..make_network_v6..ip::network_v6]
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload1 make_network_v6]``(
+ const char * str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload1 more...]]``
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload2 make_network_v6]``(
+ const char * str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload2 more...]]``
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload3 make_network_v6]``(
+ const std::string & str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload3 more...]]``
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload4 make_network_v6]``(
+ const std::string & str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload4 more...]]``
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload5 make_network_v6]``(
+ string_view str);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload5 more...]]``
+
+ network_v6 ``[link asio.reference.ip__network_v6.make_network_v6.overload6 make_network_v6]``(
+ string_view str,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.make_network_v6.overload6 more...]]``
+
+
+[section:overload1 ip::network_v6::make_network_v6 (1 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ const char * str);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v6::make_network_v6 (2 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ const char * str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::network_v6::make_network_v6 (3 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ const std::string & str);
+
+
+
+[endsect]
+
+
+
+[section:overload4 ip::network_v6::make_network_v6 (4 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ const std::string & str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload5 ip::network_v6::make_network_v6 (5 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ string_view str);
+
+
+
+[endsect]
+
+
+
+[section:overload6 ip::network_v6::make_network_v6 (6 of 6 overloads)]
+
+
+Create an IPv6 network from a string containing IP address and prefix length.
+
+
+ network_v6 make_network_v6(
+ string_view str,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:network ip::network_v6::network]
+
+[indexterm2 asio.indexterm.ip__network_v6.network..network..ip::network_v6]
+Obtain an address object that represents the network address.
+
+
+ address_v6 network() const;
+
+
+
+[endsect]
+
+
+[section:network_v6 ip::network_v6::network_v6]
+
+[indexterm2 asio.indexterm.ip__network_v6.network_v6..network_v6..ip::network_v6]
+Default constructor.
+
+
+ ``[link asio.reference.ip__network_v6.network_v6.overload1 network_v6]``();
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.network_v6.overload1 more...]]``
+
+
+Construct a network based on the specified address and prefix length.
+
+
+ ``[link asio.reference.ip__network_v6.network_v6.overload2 network_v6]``(
+ const address_v6 & addr,
+ unsigned short prefix_len);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.network_v6.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.ip__network_v6.network_v6.overload3 network_v6]``(
+ const network_v6 & other);
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.network_v6.overload3 more...]]``
+
+
+[section:overload1 ip::network_v6::network_v6 (1 of 3 overloads)]
+
+
+Default constructor.
+
+
+ network_v6();
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v6::network_v6 (2 of 3 overloads)]
+
+
+Construct a network based on the specified address and prefix length.
+
+
+ network_v6(
+ const address_v6 & addr,
+ unsigned short prefix_len);
+
+
+
+[endsect]
+
+
+
+[section:overload3 ip::network_v6::network_v6 (3 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ network_v6(
+ const network_v6 & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_not__eq_ ip::network_v6::operator!=]
+
+[indexterm2 asio.indexterm.ip__network_v6.operator_not__eq_..operator!=..ip::network_v6]
+Compare two networks for inequality.
+
+
+ friend bool operator!=(
+ const network_v6 & a,
+ const network_v6 & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ip::network_v6::operator=]
+
+[indexterm2 asio.indexterm.ip__network_v6.operator_eq_..operator=..ip::network_v6]
+Assign from another network.
+
+
+ network_v6 & operator=(
+ const network_v6 & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::network_v6::operator==]
+
+[indexterm2 asio.indexterm.ip__network_v6.operator_eq__eq_..operator==..ip::network_v6]
+Compare two networks for equality.
+
+
+ friend bool operator==(
+ const network_v6 & a,
+ const network_v6 & b);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/network_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:prefix_length ip::network_v6::prefix_length]
+
+[indexterm2 asio.indexterm.ip__network_v6.prefix_length..prefix_length..ip::network_v6]
+Obtain the prefix length that was specified when the network object was created.
+
+
+ unsigned short prefix_length() const;
+
+
+
+[endsect]
+
+
+[section:to_string ip::network_v6::to_string]
+
+[indexterm2 asio.indexterm.ip__network_v6.to_string..to_string..ip::network_v6]
+Get the network as an address in dotted decimal format.
+
+
+ std::string ``[link asio.reference.ip__network_v6.to_string.overload1 to_string]``() const;
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.to_string.overload1 more...]]``
+
+ std::string ``[link asio.reference.ip__network_v6.to_string.overload2 to_string]``(
+ asio::error_code & ec) const;
+ `` [''''&raquo;''' [link asio.reference.ip__network_v6.to_string.overload2 more...]]``
+
+
+[section:overload1 ip::network_v6::to_string (1 of 2 overloads)]
+
+
+Get the network as an address in dotted decimal format.
+
+
+ std::string to_string() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 ip::network_v6::to_string (2 of 2 overloads)]
+
+
+Get the network as an address in dotted decimal format.
+
+
+ std::string to_string(
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:ip__resolver_base ip::resolver_base]
+
+
+The [link asio.reference.ip__resolver_base `ip::resolver_base`] class is used as a base for the [link asio.reference.ip__basic_resolver `ip::basic_resolver`] class templates to provide a common place to define the flag constants.
+
+
+ class resolver_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__resolver_base.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__resolver_base._resolver_base [*~resolver_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__resolver_base.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_base.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ip/resolver_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address_configured ip::resolver_base::address_configured]
+
+[indexterm2 asio.indexterm.ip__resolver_base.address_configured..address_configured..ip::resolver_base]
+Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system.
+
+
+ static const flags address_configured = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:all_matching ip::resolver_base::all_matching]
+
+[indexterm2 asio.indexterm.ip__resolver_base.all_matching..all_matching..ip::resolver_base]
+If used with v4\_mapped, return all matching IPv6 and IPv4 addresses.
+
+
+ static const flags all_matching = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:canonical_name ip::resolver_base::canonical_name]
+
+[indexterm2 asio.indexterm.ip__resolver_base.canonical_name..canonical_name..ip::resolver_base]
+Determine the canonical name of the host specified in the query.
+
+
+ static const flags canonical_name = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:flags ip::resolver_base::flags]
+
+[indexterm2 asio.indexterm.ip__resolver_base.flags..flags..ip::resolver_base]
+A bitmask type (C++ Std [lib.bitmask.types]).
+
+
+ typedef unspecified flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/resolver_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:numeric_host ip::resolver_base::numeric_host]
+
+[indexterm2 asio.indexterm.ip__resolver_base.numeric_host..numeric_host..ip::resolver_base]
+Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted.
+
+
+ static const flags numeric_host = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:numeric_service ip::resolver_base::numeric_service]
+
+[indexterm2 asio.indexterm.ip__resolver_base.numeric_service..numeric_service..ip::resolver_base]
+Service name should be treated as a numeric string defining a port number and no name resolution should be attempted.
+
+
+ static const flags numeric_service = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:passive ip::resolver_base::passive]
+
+[indexterm2 asio.indexterm.ip__resolver_base.passive..passive..ip::resolver_base]
+Indicate that returned endpoint is intended for use as a locally bound socket endpoint.
+
+
+ static const flags passive = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:v4_mapped ip::resolver_base::v4_mapped]
+
+[indexterm2 asio.indexterm.ip__resolver_base.v4_mapped..v4_mapped..ip::resolver_base]
+If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses.
+
+
+ static const flags v4_mapped = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:_resolver_base ip::resolver_base::~resolver_base]
+
+[indexterm2 asio.indexterm.ip__resolver_base._resolver_base..~resolver_base..ip::resolver_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~resolver_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__resolver_query_base ip::resolver_query_base]
+
+
+The [link asio.reference.ip__resolver_query_base `ip::resolver_query_base`] class is used as a base for the [link asio.reference.ip__basic_resolver_query `ip::basic_resolver_query`] class templates to provide a common place to define the flag constants.
+
+
+ class resolver_query_base :
+ public ip::resolver_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__resolver_query_base.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__resolver_query_base._resolver_query_base [*~resolver_query_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__resolver_query_base.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ip/resolver_query_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:address_configured ip::resolver_query_base::address_configured]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.address_configured..address_configured..ip::resolver_query_base]
+Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system.
+
+
+ static const flags address_configured = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:all_matching ip::resolver_query_base::all_matching]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.all_matching..all_matching..ip::resolver_query_base]
+If used with v4\_mapped, return all matching IPv6 and IPv4 addresses.
+
+
+ static const flags all_matching = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:canonical_name ip::resolver_query_base::canonical_name]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.canonical_name..canonical_name..ip::resolver_query_base]
+Determine the canonical name of the host specified in the query.
+
+
+ static const flags canonical_name = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:flags ip::resolver_query_base::flags]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.flags..flags..ip::resolver_query_base]
+A bitmask type (C++ Std [lib.bitmask.types]).
+
+
+ typedef unspecified flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/resolver_query_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:numeric_host ip::resolver_query_base::numeric_host]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.numeric_host..numeric_host..ip::resolver_query_base]
+Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted.
+
+
+ static const flags numeric_host = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:numeric_service ip::resolver_query_base::numeric_service]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.numeric_service..numeric_service..ip::resolver_query_base]
+Service name should be treated as a numeric string defining a port number and no name resolution should be attempted.
+
+
+ static const flags numeric_service = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:passive ip::resolver_query_base::passive]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.passive..passive..ip::resolver_query_base]
+Indicate that returned endpoint is intended for use as a locally bound socket endpoint.
+
+
+ static const flags passive = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:v4_mapped ip::resolver_query_base::v4_mapped]
+
+
+['Inherited from ip::resolver_base.]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base.v4_mapped..v4_mapped..ip::resolver_query_base]
+If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses.
+
+
+ static const flags v4_mapped = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:_resolver_query_base ip::resolver_query_base::~resolver_query_base]
+
+[indexterm2 asio.indexterm.ip__resolver_query_base._resolver_query_base..~resolver_query_base..ip::resolver_query_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~resolver_query_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__tcp ip::tcp]
+
+
+Encapsulates the flags needed for TCP.
+
+
+ class tcp
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__tcp.acceptor [*acceptor]]]
+ [The TCP acceptor type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__tcp.endpoint [*endpoint]]]
+ [The type of a TCP endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__tcp.iostream [*iostream]]]
+ [The TCP iostream type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__tcp.no_delay [*no_delay]]]
+ [Socket option for disabling the Nagle algorithm. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__tcp.resolver [*resolver]]]
+ [The TCP resolver type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__tcp.socket [*socket]]]
+ [The TCP socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__tcp.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.ip__tcp.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__tcp.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__tcp.v4 [*v4]]]
+ [Construct to represent the IPv4 TCP protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__tcp.v6 [*v6]]]
+ [Construct to represent the IPv6 TCP protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__tcp.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__tcp.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__tcp `ip::tcp`] class contains flags necessary for TCP sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:acceptor ip::tcp::acceptor]
+
+[indexterm2 asio.indexterm.ip__tcp.acceptor..acceptor..ip::tcp]
+The TCP acceptor type.
+
+
+ typedef basic_socket_acceptor< tcp > acceptor;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.native_handle_type [*native_handle_type]]]
+ [The native representation of an acceptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.accept [*accept]]]
+ [Accept a new connection.
+
+ Accept a new connection and obtain the endpoint of the peer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.assign [*assign]]]
+ [Assigns an existing native acceptor to the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_accept [*async_accept]]]
+ [Start an asynchronous accept. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.basic_socket_acceptor [*basic_socket_acceptor]]]
+ [Construct an acceptor without opening it.
+
+ Construct an open acceptor.
+
+ Construct an acceptor opened on the given endpoint.
+
+ Construct a basic_socket_acceptor on an existing native acceptor.
+
+ Move-construct a basic_socket_acceptor from another.
+
+ Move-construct a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.bind [*bind]]]
+ [Bind the acceptor to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.close [*close]]]
+ [Close the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_option [*get_option]]]
+ [Get an option from the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.io_control [*io_control]]]
+ [Perform an IO control command on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.is_open [*is_open]]]
+ [Determine whether the acceptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.listen [*listen]]]
+ [Place the acceptor into the state where it will listen for new connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_handle [*native_handle]]]
+ [Get the native acceptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native acceptor implementation.
+
+ Sets the non-blocking mode of the native acceptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the acceptor.
+
+ Sets the non-blocking mode of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.open [*open]]]
+ [Open the acceptor using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_acceptor from another.
+
+ Move-assign a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.set_option [*set_option]]]
+ [Set an option on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.wait [*wait]]]
+ [Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor._basic_socket_acceptor [*~basic_socket_acceptor]]]
+ [Destroys the acceptor. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] class template is used for accepting new socket connections.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Example]
+
+Opening a socket acceptor with the SO\_REUSEADDR option enabled:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
+ acceptor.open(endpoint.protocol());
+ acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor.bind(endpoint);
+ acceptor.listen();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint ip::tcp::endpoint]
+
+[indexterm2 asio.indexterm.ip__tcp.endpoint..endpoint..ip::tcp]
+The type of a TCP endpoint.
+
+
+ typedef basic_endpoint< tcp > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.address [*address]]]
+ [Get the IP address associated with the endpoint.
+
+ Set the IP address associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR_ANY or in6addr_any). This constructor would typically be used for accepting new connections.
+
+ Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint.
+
+ Move-assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.port [*port]]]
+ [Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+ Set the port associated with the endpoint. The port number is always in the host's byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_endpoint `ip::basic_endpoint`] class template describes an endpoint that may be associated with a particular socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family ip::tcp::family]
+
+[indexterm2 asio.indexterm.ip__tcp.family..family..ip::tcp]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:iostream ip::tcp::iostream]
+
+[indexterm2 asio.indexterm.ip__tcp.iostream..iostream..ip::tcp]
+The TCP iostream type.
+
+
+ typedef basic_socket_iostream< tcp > iostream;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration [*duration]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration_type [*duration_type]]]
+ [(Deprecated: Use duration.) The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_point [*time_point]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_type [*time_type]]]
+ [(Deprecated: Use time_point.) The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_iostream.basic_socket_iostream [*basic_socket_iostream]]]
+ [Construct a basic_socket_iostream without establishing a connection.
+
+ Construct a basic_socket_iostream from the supplied socket.
+
+ Move-construct a basic_socket_iostream from another.
+
+ Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.close [*close]]]
+ [Close the connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.connect [*connect]]]
+ [Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.error [*error]]]
+ [Get the last error associated with the stream. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_after [*expires_after]]]
+ [Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time as an absolute time.
+
+ Set the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expiry [*expiry]]]
+ [Get the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_iostream from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.rdbuf [*rdbuf]]]
+ [Return a pointer to the underlying streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.socket [*socket]]]
+ [Get a reference to the underlying socket. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:no_delay ip::tcp::no_delay]
+
+[indexterm2 asio.indexterm.ip__tcp.no_delay..no_delay..ip::tcp]
+Socket option for disabling the Nagle algorithm.
+
+
+ typedef implementation_defined no_delay;
+
+
+
+Implements the IPPROTO\_TCP/TCP\_NODELAY socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::tcp::no_delay option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::tcp::operator!=]
+
+[indexterm2 asio.indexterm.ip__tcp.operator_not__eq_..operator!=..ip::tcp]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const tcp & p1,
+ const tcp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::tcp::operator==]
+
+[indexterm2 asio.indexterm.ip__tcp.operator_eq__eq_..operator==..ip::tcp]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const tcp & p1,
+ const tcp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol ip::tcp::protocol]
+
+[indexterm2 asio.indexterm.ip__tcp.protocol..protocol..ip::tcp]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:resolver ip::tcp::resolver]
+
+[indexterm2 asio.indexterm.ip__tcp.resolver..resolver..ip::tcp]
+The TCP resolver type.
+
+
+ typedef basic_resolver< tcp > resolver;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.iterator [*iterator]]]
+ [(Deprecated.) The iterator type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.query [*query]]]
+ [(Deprecated.) The query type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.results_type [*results_type]]]
+ [The results type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.async_resolve [*async_resolve]]]
+ [(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.basic_resolver [*basic_resolver]]]
+ [Constructor.
+
+ Move-construct a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the resolver. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.operator_eq_ [*operator=]]]
+ [Move-assign a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.resolve [*resolve]]]
+ [(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+ Perform forward resolution of a query to a list of entries.
+
+ Perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver._basic_resolver [*~basic_resolver]]]
+ [Destroys the resolver. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver `ip::basic_resolver`] class template provides the ability to resolve a query to a list of endpoints.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:socket ip::tcp::socket]
+
+[indexterm2 asio.indexterm.ip__tcp.socket..socket..ip::tcp]
+The TCP socket type.
+
+
+ typedef basic_stream_socket< tcp > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.basic_stream_socket [*basic_stream_socket]]]
+ [Construct a basic_stream_socket without opening it.
+
+ Construct and open a basic_stream_socket.
+
+ Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_stream_socket on an existing native socket.
+
+ Move-construct a basic_stream_socket from another.
+
+ Move-construct a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_stream_socket from another.
+
+ Move-assign a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.read_some [*read_some]]]
+ [Read some data from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.write_some [*write_some]]]
+ [Write some data to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket._basic_stream_socket [*~basic_stream_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_stream_socket `basic_stream_socket`] class template provides asynchronous and blocking stream-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/tcp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type ip::tcp::type]
+
+[indexterm2 asio.indexterm.ip__tcp.type..type..ip::tcp]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[section:v4 ip::tcp::v4]
+
+[indexterm2 asio.indexterm.ip__tcp.v4..v4..ip::tcp]
+Construct to represent the IPv4 TCP protocol.
+
+
+ static tcp v4();
+
+
+
+[endsect]
+
+
+
+[section:v6 ip::tcp::v6]
+
+[indexterm2 asio.indexterm.ip__tcp.v6..v6..ip::tcp]
+Construct to represent the IPv6 TCP protocol.
+
+
+ static tcp v6();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ip__udp ip::udp]
+
+
+Encapsulates the flags needed for UDP.
+
+
+ class udp
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__udp.endpoint [*endpoint]]]
+ [The type of a UDP endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__udp.resolver [*resolver]]]
+ [The UDP resolver type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__udp.socket [*socket]]]
+ [The UDP socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__udp.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.ip__udp.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__udp.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__udp.v4 [*v4]]]
+ [Construct to represent the IPv4 UDP protocol. ]
+ ]
+
+ [
+ [[link asio.reference.ip__udp.v6 [*v6]]]
+ [Construct to represent the IPv6 UDP protocol. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__udp.operator_not__eq_ [*operator!=]]]
+ [Compare two protocols for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__udp.operator_eq__eq_ [*operator==]]]
+ [Compare two protocols for equality. ]
+ ]
+
+]
+
+The [link asio.reference.ip__udp `ip::udp`] class contains flags necessary for UDP sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint ip::udp::endpoint]
+
+[indexterm2 asio.indexterm.ip__udp.endpoint..endpoint..ip::udp]
+The type of a UDP endpoint.
+
+
+ typedef basic_endpoint< udp > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.address [*address]]]
+ [Get the IP address associated with the endpoint.
+
+ Set the IP address associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using a port number, specified in the host's byte order. The IP address will be the any address (i.e. INADDR_ANY or in6addr_any). This constructor would typically be used for accepting new connections.
+
+ Construct an endpoint using a port number and an IP address. This constructor may be used for accepting connections on a specific interface or for making a connection to a remote endpoint.
+
+ Copy constructor.
+
+ Move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint.
+
+ Move-assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.port [*port]]]
+ [Get the port associated with the endpoint. The port number is always in the host's byte order.
+
+ Set the port associated with the endpoint. The port number is always in the host's byte order. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_endpoint `ip::basic_endpoint`] class template describes an endpoint that may be associated with a particular socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family ip::udp::family]
+
+[indexterm2 asio.indexterm.ip__udp.family..family..ip::udp]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ ip::udp::operator!=]
+
+[indexterm2 asio.indexterm.ip__udp.operator_not__eq_..operator!=..ip::udp]
+Compare two protocols for inequality.
+
+
+ friend bool operator!=(
+ const udp & p1,
+ const udp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ ip::udp::operator==]
+
+[indexterm2 asio.indexterm.ip__udp.operator_eq__eq_..operator==..ip::udp]
+Compare two protocols for equality.
+
+
+ friend bool operator==(
+ const udp & p1,
+ const udp & p2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol ip::udp::protocol]
+
+[indexterm2 asio.indexterm.ip__udp.protocol..protocol..ip::udp]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:resolver ip::udp::resolver]
+
+[indexterm2 asio.indexterm.ip__udp.resolver..resolver..ip::udp]
+The UDP resolver type.
+
+
+ typedef basic_resolver< udp > resolver;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.flags [*flags]]]
+ [A bitmask type (C++ Std \[lib.bitmask.types\]). ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.iterator [*iterator]]]
+ [(Deprecated.) The iterator type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.query [*query]]]
+ [(Deprecated.) The query type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ip__basic_resolver.results_type [*results_type]]]
+ [The results type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.async_resolve [*async_resolve]]]
+ [(Deprecated.) Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform forward resolution of a query to a list of entries.
+
+ Asynchronously perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.basic_resolver [*basic_resolver]]]
+ [Constructor.
+
+ Move-construct a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the resolver. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.operator_eq_ [*operator=]]]
+ [Move-assign a basic_resolver from another. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.resolve [*resolve]]]
+ [(Deprecated.) Perform forward resolution of a query to a list of entries.
+
+ Perform forward resolution of a query to a list of entries.
+
+ Perform reverse resolution of an endpoint to a list of entries. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver._basic_resolver [*~basic_resolver]]]
+ [Destroys the resolver. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ip__basic_resolver.address_configured [*address_configured]]]
+ [Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.all_matching [*all_matching]]]
+ [If used with v4_mapped, return all matching IPv6 and IPv4 addresses. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.canonical_name [*canonical_name]]]
+ [Determine the canonical name of the host specified in the query. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_host [*numeric_host]]]
+ [Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.numeric_service [*numeric_service]]]
+ [Service name should be treated as a numeric string defining a port number and no name resolution should be attempted. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.passive [*passive]]]
+ [Indicate that returned endpoint is intended for use as a locally bound socket endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.ip__basic_resolver.v4_mapped [*v4_mapped]]]
+ [If the query protocol family is specified as IPv6, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. ]
+ ]
+
+]
+
+The [link asio.reference.ip__basic_resolver `ip::basic_resolver`] class template provides the ability to resolve a query to a list of endpoints.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:socket ip::udp::socket]
+
+[indexterm2 asio.indexterm.ip__udp.socket..socket..ip::udp]
+The UDP socket type.
+
+
+ typedef basic_datagram_socket< udp > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.basic_datagram_socket [*basic_datagram_socket]]]
+ [Construct a basic_datagram_socket without opening it.
+
+ Construct and open a basic_datagram_socket.
+
+ Construct a basic_datagram_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_datagram_socket on an existing native socket.
+
+ Move-construct a basic_datagram_socket from another.
+
+ Move-construct a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_datagram_socket from another.
+
+ Move-assign a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive_from [*receive_from]]]
+ [Receive a datagram with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send_to [*send_to]]]
+ [Send a datagram to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket._basic_datagram_socket [*~basic_datagram_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_datagram_socket `basic_datagram_socket`] class template provides asynchronous and blocking datagram-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/udp.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type ip::udp::type]
+
+[indexterm2 asio.indexterm.ip__udp.type..type..ip::udp]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[section:v4 ip::udp::v4]
+
+[indexterm2 asio.indexterm.ip__udp.v4..v4..ip::udp]
+Construct to represent the IPv4 UDP protocol.
+
+
+ static udp v4();
+
+
+
+[endsect]
+
+
+
+[section:v6 ip::udp::v6]
+
+[indexterm2 asio.indexterm.ip__udp.v6..v6..ip::udp]
+Construct to represent the IPv6 UDP protocol.
+
+
+ static udp v6();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ip__unicast__hops ip::unicast::hops]
+
+[indexterm1 asio.indexterm.ip__unicast__hops..ip::unicast::hops]
+Socket option for time-to-live associated with outgoing unicast packets.
+
+
+ typedef implementation_defined hops;
+
+
+
+Implements the IPPROTO\_IP/IP\_UNICAST\_TTL socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::unicast::hops option(4);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::ip::unicast::hops option;
+ socket.get_option(option);
+ int ttl = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/unicast.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__v4_mapped_t ip::v4_mapped_t]
+
+[indexterm1 asio.indexterm.ip__v4_mapped_t..ip::v4_mapped_t]
+Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6 addresses.
+
+
+ enum v4_mapped_t
+
+[indexterm2 asio.indexterm.ip__v4_mapped_t.v4_mapped..v4_mapped..ip::v4_mapped_t]
+
+[heading Values]
+[variablelist
+
+ [
+ [v4_mapped]
+ []
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/address_v6.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:ip__v6_only ip::v6_only]
+
+[indexterm1 asio.indexterm.ip__v6_only..ip::v6_only]
+Socket option for determining whether an IPv6 socket supports IPv6 communication only.
+
+
+ typedef implementation_defined v6_only;
+
+
+
+Implements the IPPROTO\_IPV6/IP\_V6ONLY socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::v6_only option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::ip::v6_only option;
+ socket.get_option(option);
+ bool v6_only = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ip/v6_only.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:is_const_buffer_sequence is_const_buffer_sequence]
+
+
+Trait to determine whether a type satisfies the ConstBufferSequence requirements.
+
+
+ template<
+ typename T>
+ struct is_const_buffer_sequence
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:is_dynamic_buffer is_dynamic_buffer]
+
+
+Trait to determine whether a type satisfies the DynamicBuffer requirements.
+
+
+ template<
+ typename T>
+ struct is_dynamic_buffer
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:is_endpoint_sequence is_endpoint_sequence]
+
+
+Type trait used to determine whether a type is an endpoint sequence that can be used with with `connect` and `async_connect`.
+
+
+ template<
+ typename T>
+ struct is_endpoint_sequence
+
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.is_endpoint_sequence.value [*value]]]
+ [The value member is true if the type may be used as an endpoint sequence. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/connect.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:value is_endpoint_sequence::value]
+
+[indexterm2 asio.indexterm.is_endpoint_sequence.value..value..is_endpoint_sequence]
+The value member is true if the type may be used as an endpoint sequence.
+
+
+ static const bool value;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:is_executor is_executor]
+
+
+The [link asio.reference.is_executor `is_executor`] trait detects whether a type T meets the Executor type requirements.
+
+
+ template<
+ typename T>
+ struct is_executor
+
+
+Class template `is_executor` is a UnaryTypeTrait that is derived from `true_type` if the type `T` meets the syntactic requirements for Executor, otherwise `false_type`.
+
+[heading Requirements]
+
+['Header: ][^asio/is_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:is_match_condition is_match_condition]
+
+
+Type trait used to determine whether a type can be used as a match condition function with read\_until and async\_read\_until.
+
+
+ template<
+ typename T>
+ struct is_match_condition
+
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.is_match_condition.value [*value]]]
+ [The value member is true if the type may be used as a match condition. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/read_until.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:value is_match_condition::value]
+
+[indexterm2 asio.indexterm.is_match_condition.value..value..is_match_condition]
+The value member is true if the type may be used as a match condition.
+
+
+ static const bool value;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:is_mutable_buffer_sequence is_mutable_buffer_sequence]
+
+
+Trait to determine whether a type satisfies the MutableBufferSequence requirements.
+
+
+ template<
+ typename T>
+ struct is_mutable_buffer_sequence
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:is_read_buffered is_read_buffered]
+
+
+The [link asio.reference.is_read_buffered `is_read_buffered`] class is a traits class that may be used to determine whether a stream type supports buffering of read data.
+
+
+ template<
+ typename Stream>
+ class is_read_buffered
+
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.is_read_buffered.value [*value]]]
+ [The value member is true only if the Stream type supports buffering of read data. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/is_read_buffered.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:value is_read_buffered::value]
+
+[indexterm2 asio.indexterm.is_read_buffered.value..value..is_read_buffered]
+The value member is true only if the Stream type supports buffering of read data.
+
+
+ static const bool value;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:is_write_buffered is_write_buffered]
+
+
+The [link asio.reference.is_write_buffered `is_write_buffered`] class is a traits class that may be used to determine whether a stream type supports buffering of written data.
+
+
+ template<
+ typename Stream>
+ class is_write_buffered
+
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.is_write_buffered.value [*value]]]
+ [The value member is true only if the Stream type supports buffering of written data. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/is_write_buffered.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:value is_write_buffered::value]
+
+[indexterm2 asio.indexterm.is_write_buffered.value..value..is_write_buffered]
+The value member is true only if the Stream type supports buffering of written data.
+
+
+ static const bool value;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:local__basic_endpoint local::basic_endpoint]
+
+
+Describes an endpoint for a UNIX socket.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ class basic_endpoint
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using the specified path name.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.path [*path]]]
+ [Get the path associated with the endpoint.
+
+ Set the path associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.local__basic_endpoint `local::basic_endpoint`] class template describes an endpoint that may be associated with a particular UNIX socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:basic_endpoint local::basic_endpoint::basic_endpoint]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.basic_endpoint..basic_endpoint..local::basic_endpoint]
+Default constructor.
+
+
+ ``[link asio.reference.local__basic_endpoint.basic_endpoint.overload1 basic_endpoint]``();
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.basic_endpoint.overload1 more...]]``
+
+
+Construct an endpoint using the specified path name.
+
+
+ ``[link asio.reference.local__basic_endpoint.basic_endpoint.overload2 basic_endpoint]``(
+ const char * path_name);
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.basic_endpoint.overload2 more...]]``
+
+ ``[link asio.reference.local__basic_endpoint.basic_endpoint.overload3 basic_endpoint]``(
+ const std::string & path_name);
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.basic_endpoint.overload3 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.local__basic_endpoint.basic_endpoint.overload4 basic_endpoint]``(
+ const basic_endpoint & other);
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.basic_endpoint.overload4 more...]]``
+
+
+[section:overload1 local::basic_endpoint::basic_endpoint (1 of 4 overloads)]
+
+
+Default constructor.
+
+
+ basic_endpoint();
+
+
+
+[endsect]
+
+
+
+[section:overload2 local::basic_endpoint::basic_endpoint (2 of 4 overloads)]
+
+
+Construct an endpoint using the specified path name.
+
+
+ basic_endpoint(
+ const char * path_name);
+
+
+
+[endsect]
+
+
+
+[section:overload3 local::basic_endpoint::basic_endpoint (3 of 4 overloads)]
+
+
+Construct an endpoint using the specified path name.
+
+
+ basic_endpoint(
+ const std::string & path_name);
+
+
+
+[endsect]
+
+
+
+[section:overload4 local::basic_endpoint::basic_endpoint (4 of 4 overloads)]
+
+
+Copy constructor.
+
+
+ basic_endpoint(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:capacity local::basic_endpoint::capacity]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.capacity..capacity..local::basic_endpoint]
+Get the capacity of the endpoint in the native type.
+
+
+ std::size_t capacity() const;
+
+
+
+[endsect]
+
+
+[section:data local::basic_endpoint::data]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.data..data..local::basic_endpoint]
+Get the underlying endpoint in the native type.
+
+
+ data_type * ``[link asio.reference.local__basic_endpoint.data.overload1 data]``();
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.data.overload1 more...]]``
+
+ const data_type * ``[link asio.reference.local__basic_endpoint.data.overload2 data]``() const;
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.data.overload2 more...]]``
+
+
+[section:overload1 local::basic_endpoint::data (1 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ data_type * data();
+
+
+
+[endsect]
+
+
+
+[section:overload2 local::basic_endpoint::data (2 of 2 overloads)]
+
+
+Get the underlying endpoint in the native type.
+
+
+ const data_type * data() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:data_type local::basic_endpoint::data_type]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.data_type..data_type..local::basic_endpoint]
+The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer.
+
+
+ typedef implementation_defined data_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ local::basic_endpoint::operator!=]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_not__eq_..operator!=..local::basic_endpoint]
+Compare two endpoints for inequality.
+
+
+ friend bool operator!=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt_ local::basic_endpoint::operator<]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_lt_..operator<..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_lt__lt_ local::basic_endpoint::operator<<]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_lt__lt_..operator<<..local::basic_endpoint]
+Output an endpoint as a string.
+
+
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const basic_endpoint< Protocol > & endpoint);
+
+
+Used to output a human-readable string for a specified endpoint.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[os][The output stream to which the string will be written.]]
+
+[[endpoint][The endpoint to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The output stream.
+
+
+
+
+[endsect]
+
+
+
+[section:operator_lt__eq_ local::basic_endpoint::operator<=]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_lt__eq_..operator<=..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ local::basic_endpoint::operator=]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_eq_..operator=..local::basic_endpoint]
+Assign from another endpoint.
+
+
+ basic_endpoint & operator=(
+ const basic_endpoint & other);
+
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ local::basic_endpoint::operator==]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_eq__eq_..operator==..local::basic_endpoint]
+Compare two endpoints for equality.
+
+
+ friend bool operator==(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt_ local::basic_endpoint::operator>]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_gt_..operator>..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ local::basic_endpoint::operator>=]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.operator_gt__eq_..operator>=..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:path local::basic_endpoint::path]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.path..path..local::basic_endpoint]
+Get the path associated with the endpoint.
+
+
+ std::string ``[link asio.reference.local__basic_endpoint.path.overload1 path]``() const;
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.path.overload1 more...]]``
+
+
+Set the path associated with the endpoint.
+
+
+ void ``[link asio.reference.local__basic_endpoint.path.overload2 path]``(
+ const char * p);
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.path.overload2 more...]]``
+
+ void ``[link asio.reference.local__basic_endpoint.path.overload3 path]``(
+ const std::string & p);
+ `` [''''&raquo;''' [link asio.reference.local__basic_endpoint.path.overload3 more...]]``
+
+
+[section:overload1 local::basic_endpoint::path (1 of 3 overloads)]
+
+
+Get the path associated with the endpoint.
+
+
+ std::string path() const;
+
+
+
+[endsect]
+
+
+
+[section:overload2 local::basic_endpoint::path (2 of 3 overloads)]
+
+
+Set the path associated with the endpoint.
+
+
+ void path(
+ const char * p);
+
+
+
+[endsect]
+
+
+
+[section:overload3 local::basic_endpoint::path (3 of 3 overloads)]
+
+
+Set the path associated with the endpoint.
+
+
+ void path(
+ const std::string & p);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:protocol local::basic_endpoint::protocol]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.protocol..protocol..local::basic_endpoint]
+The protocol associated with the endpoint.
+
+
+ protocol_type protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:protocol_type local::basic_endpoint::protocol_type]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.protocol_type..protocol_type..local::basic_endpoint]
+The protocol type associated with the endpoint.
+
+
+ typedef Protocol protocol_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/basic_endpoint.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:resize local::basic_endpoint::resize]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.resize..resize..local::basic_endpoint]
+Set the underlying size of the endpoint in the native type.
+
+
+ void resize(
+ std::size_t new_size);
+
+
+
+[endsect]
+
+
+
+[section:size local::basic_endpoint::size]
+
+[indexterm2 asio.indexterm.local__basic_endpoint.size..size..local::basic_endpoint]
+Get the underlying size of the endpoint in the native type.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:local__connect_pair local::connect_pair]
+
+[indexterm1 asio.indexterm.local__connect_pair..local::connect_pair]
+Create a pair of connected sockets.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ void ``[link asio.reference.local__connect_pair.overload1 connect_pair]``(
+ basic_socket< Protocol > & socket1,
+ basic_socket< Protocol > & socket2);
+ `` [''''&raquo;''' [link asio.reference.local__connect_pair.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ void ``[link asio.reference.local__connect_pair.overload2 connect_pair]``(
+ basic_socket< Protocol > & socket1,
+ basic_socket< Protocol > & socket2,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.local__connect_pair.overload2 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/local/connect_pair.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 local::connect_pair (1 of 2 overloads)]
+
+
+Create a pair of connected sockets.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ void connect_pair(
+ basic_socket< Protocol > & socket1,
+ basic_socket< Protocol > & socket2);
+
+
+
+[endsect]
+
+
+
+[section:overload2 local::connect_pair (2 of 2 overloads)]
+
+
+Create a pair of connected sockets.
+
+
+ template<
+ typename ``[link asio.reference.Protocol Protocol]``>
+ void connect_pair(
+ basic_socket< Protocol > & socket1,
+ basic_socket< Protocol > & socket2,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:local__datagram_protocol local::datagram_protocol]
+
+
+Encapsulates the flags needed for datagram-oriented UNIX sockets.
+
+
+ class datagram_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.local__datagram_protocol.endpoint [*endpoint]]]
+ [The type of a UNIX domain endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__datagram_protocol.socket [*socket]]]
+ [The UNIX domain socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__datagram_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.local__datagram_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.local__datagram_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+The [link asio.reference.local__datagram_protocol `local::datagram_protocol`] class contains flags necessary for datagram-oriented UNIX domain sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:endpoint local::datagram_protocol::endpoint]
+
+[indexterm2 asio.indexterm.local__datagram_protocol.endpoint..endpoint..local::datagram_protocol]
+The type of a UNIX domain endpoint.
+
+
+ typedef basic_endpoint< datagram_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using the specified path name.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.path [*path]]]
+ [Get the path associated with the endpoint.
+
+ Set the path associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.local__basic_endpoint `local::basic_endpoint`] class template describes an endpoint that may be associated with a particular UNIX socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family local::datagram_protocol::family]
+
+[indexterm2 asio.indexterm.local__datagram_protocol.family..family..local::datagram_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:protocol local::datagram_protocol::protocol]
+
+[indexterm2 asio.indexterm.local__datagram_protocol.protocol..protocol..local::datagram_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:socket local::datagram_protocol::socket]
+
+[indexterm2 asio.indexterm.local__datagram_protocol.socket..socket..local::datagram_protocol]
+The UNIX domain socket type.
+
+
+ typedef basic_datagram_socket< datagram_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_datagram_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_receive_from [*async_receive_from]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send [*async_send]]]
+ [Start an asynchronous send on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_send_to [*async_send_to]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.basic_datagram_socket [*basic_datagram_socket]]]
+ [Construct a basic_datagram_socket without opening it.
+
+ Construct and open a basic_datagram_socket.
+
+ Construct a basic_datagram_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_datagram_socket on an existing native socket.
+
+ Move-construct a basic_datagram_socket from another.
+
+ Move-construct a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_datagram_socket from another.
+
+ Move-assign a basic_datagram_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive [*receive]]]
+ [Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.receive_from [*receive_from]]]
+ [Receive a datagram with the endpoint of the sender. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send [*send]]]
+ [Send some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.send_to [*send_to]]]
+ [Send a datagram to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket._basic_datagram_socket [*~basic_datagram_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_datagram_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_datagram_socket `basic_datagram_socket`] class template provides asynchronous and blocking datagram-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/datagram_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type local::datagram_protocol::type]
+
+[indexterm2 asio.indexterm.local__datagram_protocol.type..type..local::datagram_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:local__stream_protocol local::stream_protocol]
+
+
+Encapsulates the flags needed for stream-oriented UNIX sockets.
+
+
+ class stream_protocol
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.local__stream_protocol.acceptor [*acceptor]]]
+ [The UNIX domain acceptor type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__stream_protocol.endpoint [*endpoint]]]
+ [The type of a UNIX domain endpoint. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__stream_protocol.iostream [*iostream]]]
+ [The UNIX domain iostream type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__stream_protocol.socket [*socket]]]
+ [The UNIX domain socket type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__stream_protocol.family [*family]]]
+ [Obtain an identifier for the protocol family. ]
+ ]
+
+ [
+ [[link asio.reference.local__stream_protocol.protocol [*protocol]]]
+ [Obtain an identifier for the protocol. ]
+ ]
+
+ [
+ [[link asio.reference.local__stream_protocol.type [*type]]]
+ [Obtain an identifier for the type of the protocol. ]
+ ]
+
+]
+
+The [link asio.reference.local__stream_protocol `local::stream_protocol`] class contains flags necessary for stream-oriented UNIX domain sockets.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Safe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:acceptor local::stream_protocol::acceptor]
+
+[indexterm2 asio.indexterm.local__stream_protocol.acceptor..acceptor..local::stream_protocol]
+The UNIX domain acceptor type.
+
+
+ typedef basic_socket_acceptor< stream_protocol > acceptor;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.native_handle_type [*native_handle_type]]]
+ [The native representation of an acceptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_acceptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.accept [*accept]]]
+ [Accept a new connection.
+
+ Accept a new connection and obtain the endpoint of the peer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.assign [*assign]]]
+ [Assigns an existing native acceptor to the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_accept [*async_accept]]]
+ [Start an asynchronous accept. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.basic_socket_acceptor [*basic_socket_acceptor]]]
+ [Construct an acceptor without opening it.
+
+ Construct an open acceptor.
+
+ Construct an acceptor opened on the given endpoint.
+
+ Construct a basic_socket_acceptor on an existing native acceptor.
+
+ Move-construct a basic_socket_acceptor from another.
+
+ Move-construct a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.bind [*bind]]]
+ [Bind the acceptor to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.close [*close]]]
+ [Close the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.get_option [*get_option]]]
+ [Get an option from the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.io_control [*io_control]]]
+ [Perform an IO control command on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.is_open [*is_open]]]
+ [Determine whether the acceptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.listen [*listen]]]
+ [Place the acceptor into the state where it will listen for new connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_handle [*native_handle]]]
+ [Get the native acceptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native acceptor implementation.
+
+ Sets the non-blocking mode of the native acceptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the acceptor.
+
+ Sets the non-blocking mode of the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.open [*open]]]
+ [Open the acceptor using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_acceptor from another.
+
+ Move-assign a basic_socket_acceptor from an acceptor of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.set_option [*set_option]]]
+ [Set an option on the acceptor. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.wait [*wait]]]
+ [Wait for the acceptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor._basic_socket_acceptor [*~basic_socket_acceptor]]]
+ [Destroys the acceptor. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_acceptor.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_socket_acceptor `basic_socket_acceptor`] class template is used for accepting new socket connections.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Example]
+
+Opening a socket acceptor with the SO\_REUSEADDR option enabled:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
+ acceptor.open(endpoint.protocol());
+ acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor.bind(endpoint);
+ acceptor.listen();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:endpoint local::stream_protocol::endpoint]
+
+[indexterm2 asio.indexterm.local__stream_protocol.endpoint..endpoint..local::stream_protocol]
+The type of a UNIX domain endpoint.
+
+
+ typedef basic_endpoint< stream_protocol > endpoint;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.data_type [*data_type]]]
+ [The type of the endpoint structure. This type is dependent on the underlying implementation of the socket layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.local__basic_endpoint.protocol_type [*protocol_type]]]
+ [The protocol type associated with the endpoint. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.basic_endpoint [*basic_endpoint]]]
+ [Default constructor.
+
+ Construct an endpoint using the specified path name.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.capacity [*capacity]]]
+ [Get the capacity of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.data [*data]]]
+ [Get the underlying endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq_ [*operator=]]]
+ [Assign from another endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.path [*path]]]
+ [Get the path associated with the endpoint.
+
+ Set the path associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.protocol [*protocol]]]
+ [The protocol associated with the endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.resize [*resize]]]
+ [Set the underlying size of the endpoint in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.size [*size]]]
+ [Get the underlying size of the endpoint in the native type. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_not__eq_ [*operator!=]]]
+ [Compare two endpoints for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt_ [*operator<]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
+ [Compare two endpoints for equality. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.local__basic_endpoint.operator_lt__lt_ [*operator<<]]]
+ [Output an endpoint as a string. ]
+ ]
+
+]
+
+The [link asio.reference.local__basic_endpoint `local::basic_endpoint`] class template describes an endpoint that may be associated with a particular UNIX socket.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:family local::stream_protocol::family]
+
+[indexterm2 asio.indexterm.local__stream_protocol.family..family..local::stream_protocol]
+Obtain an identifier for the protocol family.
+
+
+ int family() const;
+
+
+
+[endsect]
+
+
+
+[section:iostream local::stream_protocol::iostream]
+
+[indexterm2 asio.indexterm.local__stream_protocol.iostream..iostream..local::stream_protocol]
+The UNIX domain iostream type.
+
+
+ typedef basic_socket_iostream< stream_protocol > iostream;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration [*duration]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.duration_type [*duration_type]]]
+ [(Deprecated: Use duration.) The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_point [*time_point]]]
+ [The time type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_socket_iostream.time_type [*time_type]]]
+ [(Deprecated: Use time_point.) The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_socket_iostream.basic_socket_iostream [*basic_socket_iostream]]]
+ [Construct a basic_socket_iostream without establishing a connection.
+
+ Construct a basic_socket_iostream from the supplied socket.
+
+ Move-construct a basic_socket_iostream from another.
+
+ Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.close [*close]]]
+ [Close the connection. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.connect [*connect]]]
+ [Establish a connection to an endpoint corresponding to a resolver query. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.error [*error]]]
+ [Get the last error associated with the stream. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_after [*expires_after]]]
+ [Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time as an absolute time.
+
+ Set the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the stream's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the stream's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.expiry [*expiry]]]
+ [Get the stream's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.operator_eq_ [*operator=]]]
+ [Move-assign a basic_socket_iostream from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.rdbuf [*rdbuf]]]
+ [Return a pointer to the underlying streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_socket_iostream.socket [*socket]]]
+ [Get a reference to the underlying socket. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:protocol local::stream_protocol::protocol]
+
+[indexterm2 asio.indexterm.local__stream_protocol.protocol..protocol..local::stream_protocol]
+Obtain an identifier for the protocol.
+
+
+ int protocol() const;
+
+
+
+[endsect]
+
+
+
+[section:socket local::stream_protocol::socket]
+
+[indexterm2 asio.indexterm.local__stream_protocol.socket..socket..local::stream_protocol]
+The UNIX domain socket type.
+
+
+ typedef basic_stream_socket< stream_protocol > socket;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.endpoint_type [*endpoint_type]]]
+ [The endpoint type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_socket is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.native_handle_type [*native_handle_type]]]
+ [The native representation of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.protocol_type [*protocol_type]]]
+ [The protocol type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_stream_socket.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.assign [*assign]]]
+ [Assign an existing native socket to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_connect [*async_connect]]]
+ [Start an asynchronous connect. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_receive [*async_receive]]]
+ [Start an asynchronous receive. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_send [*async_send]]]
+ [Start an asynchronous send. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_wait [*async_wait]]]
+ [Asynchronously wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.at_mark [*at_mark]]]
+ [Determine whether the socket is at the out-of-band data mark. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.available [*available]]]
+ [Determine the number of bytes available for reading. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.basic_stream_socket [*basic_stream_socket]]]
+ [Construct a basic_stream_socket without opening it.
+
+ Construct and open a basic_stream_socket.
+
+ Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
+
+ Construct a basic_stream_socket on an existing native socket.
+
+ Move-construct a basic_stream_socket from another.
+
+ Move-construct a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.bind [*bind]]]
+ [Bind the socket to the given local endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.close [*close]]]
+ [Close the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.connect [*connect]]]
+ [Connect the socket to the specified endpoint. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.get_option [*get_option]]]
+ [Get an option from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.io_control [*io_control]]]
+ [Perform an IO control command on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.is_open [*is_open]]]
+ [Determine whether the socket is open. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.local_endpoint [*local_endpoint]]]
+ [Get the local endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_handle [*native_handle]]]
+ [Get the native socket representation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native socket implementation.
+
+ Sets the non-blocking mode of the native socket implementation. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the socket.
+
+ Sets the non-blocking mode of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.open [*open]]]
+ [Open the socket using the specified protocol. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.operator_eq_ [*operator=]]]
+ [Move-assign a basic_stream_socket from another.
+
+ Move-assign a basic_stream_socket from a socket of another protocol type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.read_some [*read_some]]]
+ [Read some data from the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.receive [*receive]]]
+ [Receive some data on the socket.
+
+ Receive some data on a connected socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.remote_endpoint [*remote_endpoint]]]
+ [Get the remote endpoint of the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.send [*send]]]
+ [Send some data on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.set_option [*set_option]]]
+ [Set an option on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.shutdown [*shutdown]]]
+ [Disable sends or receives on the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.wait [*wait]]]
+ [Wait for the socket to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.write_some [*write_some]]]
+ [Write some data to the socket. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket._basic_stream_socket [*~basic_stream_socket]]]
+ [Destroys the socket. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.basic_stream_socket.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+The [link asio.reference.basic_stream_socket `basic_stream_socket`] class template provides asynchronous and blocking stream-oriented socket functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/local/stream_protocol.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:type local::stream_protocol::type]
+
+[indexterm2 asio.indexterm.local__stream_protocol.type..type..local::stream_protocol]
+Obtain an identifier for the type of the protocol.
+
+
+ int type() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:make_work_guard make_work_guard]
+
+[indexterm1 asio.indexterm.make_work_guard..make_work_guard]
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor_work_guard< Executor > ``[link asio.reference.make_work_guard.overload1 make_work_guard]``(
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.make_work_guard.overload1 more...]]``
+
+ template<
+ typename ExecutionContext>
+ executor_work_guard< typename ExecutionContext::executor_type > ``[link asio.reference.make_work_guard.overload2 make_work_guard]``(
+ ExecutionContext & ctx,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.make_work_guard.overload2 more...]]``
+
+ template<
+ typename T>
+ executor_work_guard< typename associated_executor< T >::type > ``[link asio.reference.make_work_guard.overload3 make_work_guard]``(
+ const T & t,
+ typename enable_if<!is_executor< T >::value &&!is_convertible< T &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.make_work_guard.overload3 more...]]``
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor_work_guard< typename associated_executor< T, Executor >::type > ``[link asio.reference.make_work_guard.overload4 make_work_guard]``(
+ const T & t,
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.make_work_guard.overload4 more...]]``
+
+ template<
+ typename T,
+ typename ExecutionContext>
+ executor_work_guard< typename associated_executor< T, typename ExecutionContext::executor_type >::type > ``[link asio.reference.make_work_guard.overload5 make_work_guard]``(
+ const T & t,
+ ExecutionContext & ctx,
+ typename enable_if<!is_executor< T >::value &&!is_convertible< T &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.make_work_guard.overload5 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/executor_work_guard.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 make_work_guard (1 of 5 overloads)]
+
+
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor_work_guard< Executor > make_work_guard(
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload2 make_work_guard (2 of 5 overloads)]
+
+
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename ExecutionContext>
+ executor_work_guard< typename ExecutionContext::executor_type > make_work_guard(
+ ExecutionContext & ctx,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload3 make_work_guard (3 of 5 overloads)]
+
+
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename T>
+ executor_work_guard< typename associated_executor< T >::type > make_work_guard(
+ const T & t,
+ typename enable_if<!is_executor< T >::value &&!is_convertible< T &, execution_context & >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload4 make_work_guard (4 of 5 overloads)]
+
+
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ executor_work_guard< typename associated_executor< T, Executor >::type > make_work_guard(
+ const T & t,
+ const Executor & ex,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+
+[section:overload5 make_work_guard (5 of 5 overloads)]
+
+
+Create an [link asio.reference.executor_work_guard `executor_work_guard`] object.
+
+
+ template<
+ typename T,
+ typename ExecutionContext>
+ executor_work_guard< typename associated_executor< T, typename ExecutionContext::executor_type >::type > make_work_guard(
+ const T & t,
+ ExecutionContext & ctx,
+ typename enable_if<!is_executor< T >::value &&!is_convertible< T &, execution_context & >::value >::type * = 0);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:mutable_buffer mutable_buffer]
+
+
+Holds a buffer that can be modified.
+
+
+ class mutable_buffer
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.mutable_buffer [*mutable_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.mutable_buffer `mutable_buffer`] class provides a safe representation of a buffer that can be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:data mutable_buffer::data]
+
+[indexterm2 asio.indexterm.mutable_buffer.data..data..mutable_buffer]
+Get a pointer to the beginning of the memory range.
+
+
+ void * data() const;
+
+
+
+[endsect]
+
+
+[section:mutable_buffer mutable_buffer::mutable_buffer]
+
+[indexterm2 asio.indexterm.mutable_buffer.mutable_buffer..mutable_buffer..mutable_buffer]
+Construct an empty buffer.
+
+
+ ``[link asio.reference.mutable_buffer.mutable_buffer.overload1 mutable_buffer]``();
+ `` [''''&raquo;''' [link asio.reference.mutable_buffer.mutable_buffer.overload1 more...]]``
+
+
+Construct a buffer to represent a given memory range.
+
+
+ ``[link asio.reference.mutable_buffer.mutable_buffer.overload2 mutable_buffer]``(
+ void * data,
+ std::size_t size);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffer.mutable_buffer.overload2 more...]]``
+
+
+[section:overload1 mutable_buffer::mutable_buffer (1 of 2 overloads)]
+
+
+Construct an empty buffer.
+
+
+ mutable_buffer();
+
+
+
+[endsect]
+
+
+
+[section:overload2 mutable_buffer::mutable_buffer (2 of 2 overloads)]
+
+
+Construct a buffer to represent a given memory range.
+
+
+ mutable_buffer(
+ void * data,
+ std::size_t size);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_plus_ mutable_buffer::operator+]
+
+[indexterm2 asio.indexterm.mutable_buffer.operator_plus_..operator+..mutable_buffer]
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer ``[link asio.reference.mutable_buffer.operator_plus_.overload1 operator+]``(
+ const mutable_buffer & b,
+ std::size_t n);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffer.operator_plus_.overload1 more...]]``
+
+ mutable_buffer ``[link asio.reference.mutable_buffer.operator_plus_.overload2 operator+]``(
+ std::size_t n,
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffer.operator_plus_.overload2 more...]]``
+
+
+[section:overload1 mutable_buffer::operator+ (1 of 2 overloads)]
+
+
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer operator+(
+ const mutable_buffer & b,
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:overload2 mutable_buffer::operator+ (2 of 2 overloads)]
+
+
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer operator+(
+ std::size_t n,
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_plus__eq_ mutable_buffer::operator+=]
+
+[indexterm2 asio.indexterm.mutable_buffer.operator_plus__eq_..operator+=..mutable_buffer]
+Move the start of the buffer by the specified number of bytes.
+
+
+ mutable_buffer & operator+=(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size mutable_buffer::size]
+
+[indexterm2 asio.indexterm.mutable_buffer.size..size..mutable_buffer]
+Get the size of the memory range.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:mutable_buffers_1 mutable_buffers_1]
+
+
+(Deprecated: Use [link asio.reference.mutable_buffer `mutable_buffer`].) Adapts a single modifiable buffer so that it meets the requirements of the MutableBufferSequence concept.
+
+
+ class mutable_buffers_1 :
+ public mutable_buffer
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.mutable_buffers_1.const_iterator [*const_iterator]]]
+ [A random-access iterator type that may be used to read elements. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.mutable_buffers_1.value_type [*value_type]]]
+ [The type for each element in the list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffers_1.begin [*begin]]]
+ [Get a random-access iterator to the first element. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffers_1.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffers_1.end [*end]]]
+ [Get a random-access iterator for one past the last element. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffers_1.mutable_buffers_1 [*mutable_buffers_1]]]
+ [Construct to represent a given memory range.
+
+ Construct to represent a single modifiable buffer. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffers_1.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffers_1.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffers_1.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:begin mutable_buffers_1::begin]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.begin..begin..mutable_buffers_1]
+Get a random-access iterator to the first element.
+
+
+ const_iterator begin() const;
+
+
+
+[endsect]
+
+
+
+[section:const_iterator mutable_buffers_1::const_iterator]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.const_iterator..const_iterator..mutable_buffers_1]
+A random-access iterator type that may be used to read elements.
+
+
+ typedef const mutable_buffer * const_iterator;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:data mutable_buffers_1::data]
+
+
+['Inherited from mutable_buffer.]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.data..data..mutable_buffers_1]
+Get a pointer to the beginning of the memory range.
+
+
+ void * data() const;
+
+
+
+[endsect]
+
+
+
+[section:end mutable_buffers_1::end]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.end..end..mutable_buffers_1]
+Get a random-access iterator for one past the last element.
+
+
+ const_iterator end() const;
+
+
+
+[endsect]
+
+
+[section:mutable_buffers_1 mutable_buffers_1::mutable_buffers_1]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.mutable_buffers_1..mutable_buffers_1..mutable_buffers_1]
+Construct to represent a given memory range.
+
+
+ ``[link asio.reference.mutable_buffers_1.mutable_buffers_1.overload1 mutable_buffers_1]``(
+ void * data,
+ std::size_t size);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffers_1.mutable_buffers_1.overload1 more...]]``
+
+
+Construct to represent a single modifiable buffer.
+
+
+ explicit ``[link asio.reference.mutable_buffers_1.mutable_buffers_1.overload2 mutable_buffers_1]``(
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffers_1.mutable_buffers_1.overload2 more...]]``
+
+
+[section:overload1 mutable_buffers_1::mutable_buffers_1 (1 of 2 overloads)]
+
+
+Construct to represent a given memory range.
+
+
+ mutable_buffers_1(
+ void * data,
+ std::size_t size);
+
+
+
+[endsect]
+
+
+
+[section:overload2 mutable_buffers_1::mutable_buffers_1 (2 of 2 overloads)]
+
+
+Construct to represent a single modifiable buffer.
+
+
+ mutable_buffers_1(
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:operator_plus_ mutable_buffers_1::operator+]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.operator_plus_..operator+..mutable_buffers_1]
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer ``[link asio.reference.mutable_buffers_1.operator_plus_.overload1 operator+]``(
+ const mutable_buffer & b,
+ std::size_t n);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffers_1.operator_plus_.overload1 more...]]``
+
+ mutable_buffer ``[link asio.reference.mutable_buffers_1.operator_plus_.overload2 operator+]``(
+ std::size_t n,
+ const mutable_buffer & b);
+ `` [''''&raquo;''' [link asio.reference.mutable_buffers_1.operator_plus_.overload2 more...]]``
+
+
+[section:overload1 mutable_buffers_1::operator+ (1 of 2 overloads)]
+
+
+['Inherited from mutable_buffer.]
+
+
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer operator+(
+ const mutable_buffer & b,
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:overload2 mutable_buffers_1::operator+ (2 of 2 overloads)]
+
+
+['Inherited from mutable_buffer.]
+
+
+Create a new modifiable buffer that is offset from the start of another.
+
+
+ mutable_buffer operator+(
+ std::size_t n,
+ const mutable_buffer & b);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_plus__eq_ mutable_buffers_1::operator+=]
+
+
+['Inherited from mutable_buffer.]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.operator_plus__eq_..operator+=..mutable_buffers_1]
+Move the start of the buffer by the specified number of bytes.
+
+
+ mutable_buffer & operator+=(
+ std::size_t n);
+
+
+
+[endsect]
+
+
+
+[section:size mutable_buffers_1::size]
+
+
+['Inherited from mutable_buffer.]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.size..size..mutable_buffers_1]
+Get the size of the memory range.
+
+
+ std::size_t size() const;
+
+
+
+[endsect]
+
+
+
+[section:value_type mutable_buffers_1::value_type]
+
+[indexterm2 asio.indexterm.mutable_buffers_1.value_type..value_type..mutable_buffers_1]
+The type for each element in the list of buffers.
+
+
+ typedef mutable_buffer value_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.mutable_buffer [*mutable_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.mutable_buffer `mutable_buffer`] class provides a safe representation of a buffer that can be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:null_buffers null_buffers]
+
+
+(Deprecated: Use the socket/descriptor wait() and async\_wait() member functions.) An implementation of both the ConstBufferSequence and MutableBufferSequence concepts to represent a null buffer sequence.
+
+
+ class null_buffers
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.null_buffers.const_iterator [*const_iterator]]]
+ [A random-access iterator type that may be used to read elements. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.null_buffers.value_type [*value_type]]]
+ [The type for each element in the list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.null_buffers.begin [*begin]]]
+ [Get a random-access iterator to the first element. ]
+ ]
+
+ [
+ [[link asio.reference.null_buffers.end [*end]]]
+ [Get a random-access iterator for one past the last element. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:begin null_buffers::begin]
+
+[indexterm2 asio.indexterm.null_buffers.begin..begin..null_buffers]
+Get a random-access iterator to the first element.
+
+
+ const_iterator begin() const;
+
+
+
+[endsect]
+
+
+
+[section:const_iterator null_buffers::const_iterator]
+
+[indexterm2 asio.indexterm.null_buffers.const_iterator..const_iterator..null_buffers]
+A random-access iterator type that may be used to read elements.
+
+
+ typedef const mutable_buffer * const_iterator;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:end null_buffers::end]
+
+[indexterm2 asio.indexterm.null_buffers.end..end..null_buffers]
+Get a random-access iterator for one past the last element.
+
+
+ const_iterator end() const;
+
+
+
+[endsect]
+
+
+
+[section:value_type null_buffers::value_type]
+
+[indexterm2 asio.indexterm.null_buffers.value_type..value_type..null_buffers]
+The type for each element in the list of buffers.
+
+
+ typedef mutable_buffer value_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.data [*data]]]
+ [Get a pointer to the beginning of the memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.mutable_buffer [*mutable_buffer]]]
+ [Construct an empty buffer.
+
+ Construct a buffer to represent a given memory range. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus__eq_ [*operator+=]]]
+ [Move the start of the buffer by the specified number of bytes. ]
+ ]
+
+ [
+ [[link asio.reference.mutable_buffer.size [*size]]]
+ [Get the size of the memory range. ]
+ ]
+
+]
+
+[heading Related Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.mutable_buffer.operator_plus_ [*operator+]]]
+ [Create a new modifiable buffer that is offset from the start of another. ]
+ ]
+
+]
+
+The [link asio.reference.mutable_buffer `mutable_buffer`] class provides a safe representation of a buffer that can be modified. It does not own the underlying data, and so is cheap to copy or assign.
+
+
+[heading Accessing Buffer Contents]
+
+
+
+The contents of a buffer may be accessed using the `data()` and `size()` member functions:
+
+
+
+ asio::mutable_buffer b1 = ...;
+ std::size_t s1 = b1.size();
+ unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+
+
+
+
+The `data()` member function permits violations of type safety, so uses of it in application code should be carefully considered.
+
+
+[heading Requirements]
+
+['Header: ][^asio/buffer.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:operator_lt__lt_ operator<<]
+
+[indexterm1 asio.indexterm.operator_lt__lt_..operator<<]
+Output an error code.
+
+
+ template<
+ typename Elem,
+ typename Traits>
+ std::basic_ostream< Elem, Traits > & operator<<(
+ std::basic_ostream< Elem, Traits > & os,
+ const error_code & ec);
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__bytes_transferred placeholders::bytes_transferred]
+
+[indexterm1 asio.indexterm.placeholders__bytes_transferred..placeholders::bytes_transferred]
+An argument placeholder, for use with boost::bind(), that corresponds to the bytes\_transferred argument of a handler for asynchronous functions such as `asio::basic_stream_socket::async_write_some` or `asio::async_write`.
+
+
+ unspecified bytes_transferred;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__endpoint placeholders::endpoint]
+
+[indexterm1 asio.indexterm.placeholders__endpoint..placeholders::endpoint]
+An argument placeholder, for use with boost::bind(), that corresponds to the results argument of a handler for asynchronous functions such as `asio::async_connect`.
+
+
+ unspecified endpoint;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__error placeholders::error]
+
+[indexterm1 asio.indexterm.placeholders__error..placeholders::error]
+An argument placeholder, for use with boost::bind(), that corresponds to the error argument of a handler for any of the asynchronous functions.
+
+
+ unspecified error;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__iterator placeholders::iterator]
+
+[indexterm1 asio.indexterm.placeholders__iterator..placeholders::iterator]
+An argument placeholder, for use with boost::bind(), that corresponds to the iterator argument of a handler for asynchronous functions such as `asio::async_connect`.
+
+
+ unspecified iterator;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__results placeholders::results]
+
+[indexterm1 asio.indexterm.placeholders__results..placeholders::results]
+An argument placeholder, for use with boost::bind(), that corresponds to the results argument of a handler for asynchronous functions such as asio::basic\_resolver::async\_resolve.
+
+
+ unspecified results;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:placeholders__signal_number placeholders::signal_number]
+
+[indexterm1 asio.indexterm.placeholders__signal_number..placeholders::signal_number]
+An argument placeholder, for use with boost::bind(), that corresponds to the signal\_number argument of a handler for asynchronous functions such as `asio::signal_set::async_wait`.
+
+
+ unspecified signal_number;
+
+
+[heading Requirements]
+
+['Header: ][^asio/placeholders.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:posix__descriptor posix::descriptor]
+
+
+Provides POSIX descriptor functionality.
+
+
+ class descriptor :
+ public posix::descriptor_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.posix__descriptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.lowest_layer_type [*lowest_layer_type]]]
+ [A descriptor is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.native_handle_type [*native_handle_type]]]
+ [The native representation of a descriptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor.assign [*assign]]]
+ [Assign an existing native descriptor to the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.close [*close]]]
+ [Close the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.descriptor [*descriptor]]]
+ [Construct a descriptor without opening it.
+
+ Construct a descriptor on an existing native descriptor.
+
+ Move-construct a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.io_control [*io_control]]]
+ [Perform an IO control command on the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.is_open [*is_open]]]
+ [Determine whether the descriptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_handle [*native_handle]]]
+ [Get the native descriptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native descriptor implementation.
+
+ Sets the non-blocking mode of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the descriptor.
+
+ Sets the non-blocking mode of the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.operator_eq_ [*operator=]]]
+ [Move-assign a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.release [*release]]]
+ [Release ownership of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.wait [*wait]]]
+ [Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor._descriptor [*~descriptor]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.posix__descriptor `posix::descriptor`] class template provides the ability to wrap a POSIX descriptor.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign posix::descriptor::assign]
+
+[indexterm2 asio.indexterm.posix__descriptor.assign..assign..posix::descriptor]
+Assign an existing native descriptor to the descriptor.
+
+
+ void ``[link asio.reference.posix__descriptor.assign.overload1 assign]``(
+ const native_handle_type & native_descriptor);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.assign.overload1 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.assign.overload2 assign]``(
+ const native_handle_type & native_descriptor,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.assign.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::assign (1 of 2 overloads)]
+
+
+Assign an existing native descriptor to the descriptor.
+
+
+ void assign(
+ const native_handle_type & native_descriptor);
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::assign (2 of 2 overloads)]
+
+
+Assign an existing native descriptor to the descriptor.
+
+
+ void assign(
+ const native_handle_type & native_descriptor,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait posix::descriptor::async_wait]
+
+[indexterm2 asio.indexterm.posix__descriptor.async_wait..async_wait..posix::descriptor]
+Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ descriptor.async_wait(
+ asio::posix::stream_descriptor::wait_read,
+ wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:bytes_readable posix::descriptor::bytes_readable]
+
+[indexterm2 asio.indexterm.posix__descriptor.bytes_readable..bytes_readable..posix::descriptor]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::descriptor_base::bytes_readable command(true);
+ descriptor.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel posix::descriptor::cancel]
+
+[indexterm2 asio.indexterm.posix__descriptor.cancel..cancel..posix::descriptor]
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void ``[link asio.reference.posix__descriptor.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.cancel.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close posix::descriptor::close]
+
+[indexterm2 asio.indexterm.posix__descriptor.close..close..posix::descriptor]
+Close the descriptor.
+
+
+ void ``[link asio.reference.posix__descriptor.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.close.overload1 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.close.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::close (1 of 2 overloads)]
+
+
+Close the descriptor.
+
+
+ void close();
+
+
+This function is used to close the descriptor. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::close (2 of 2 overloads)]
+
+
+Close the descriptor.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the descriptor. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:descriptor posix::descriptor::descriptor]
+
+[indexterm2 asio.indexterm.posix__descriptor.descriptor..descriptor..posix::descriptor]
+Construct a descriptor without opening it.
+
+
+ explicit ``[link asio.reference.posix__descriptor.descriptor.overload1 descriptor]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.descriptor.overload1 more...]]``
+
+
+Construct a descriptor on an existing native descriptor.
+
+
+ ``[link asio.reference.posix__descriptor.descriptor.overload2 descriptor]``(
+ asio::io_context & io_context,
+ const native_handle_type & native_descriptor);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.descriptor.overload2 more...]]``
+
+
+Move-construct a descriptor from another.
+
+
+ ``[link asio.reference.posix__descriptor.descriptor.overload3 descriptor]``(
+ descriptor && other);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.descriptor.overload3 more...]]``
+
+
+[section:overload1 posix::descriptor::descriptor (1 of 3 overloads)]
+
+
+Construct a descriptor without opening it.
+
+
+ descriptor(
+ asio::io_context & io_context);
+
+
+This constructor creates a descriptor without opening it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the descriptor will use to dispatch handlers for any asynchronous operations performed on the descriptor. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::descriptor (2 of 3 overloads)]
+
+
+Construct a descriptor on an existing native descriptor.
+
+
+ descriptor(
+ asio::io_context & io_context,
+ const native_handle_type & native_descriptor);
+
+
+This constructor creates a descriptor object to hold an existing native descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the descriptor will use to dispatch handlers for any asynchronous operations performed on the descriptor.]]
+
+[[native_descriptor][A native descriptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::descriptor::descriptor (3 of 3 overloads)]
+
+
+Move-construct a descriptor from another.
+
+
+ descriptor(
+ descriptor && other);
+
+
+This constructor moves a descriptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other descriptor object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `descriptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type posix::descriptor::executor_type]
+
+[indexterm2 asio.indexterm.posix__descriptor.executor_type..executor_type..posix::descriptor]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor posix::descriptor::get_executor]
+
+[indexterm2 asio.indexterm.posix__descriptor.get_executor..get_executor..posix::descriptor]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context posix::descriptor::get_io_context]
+
+[indexterm2 asio.indexterm.posix__descriptor.get_io_context..get_io_context..posix::descriptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service posix::descriptor::get_io_service]
+
+[indexterm2 asio.indexterm.posix__descriptor.get_io_service..get_io_service..posix::descriptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:io_control posix::descriptor::io_control]
+
+[indexterm2 asio.indexterm.posix__descriptor.io_control..io_control..posix::descriptor]
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.posix__descriptor.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.posix__descriptor.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.io_control.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::io_control (1 of 2 overloads)]
+
+
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the descriptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::posix::stream_descriptor::bytes_readable command;
+ descriptor.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::io_control (2 of 2 overloads)]
+
+
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the descriptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::posix::stream_descriptor::bytes_readable command;
+ asio::error_code ec;
+ descriptor.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open posix::descriptor::is_open]
+
+[indexterm2 asio.indexterm.posix__descriptor.is_open..is_open..posix::descriptor]
+Determine whether the descriptor is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer posix::descriptor::lowest_layer]
+
+[indexterm2 asio.indexterm.posix__descriptor.lowest_layer..lowest_layer..posix::descriptor]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.posix__descriptor.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.posix__descriptor.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a descriptor cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a descriptor cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type posix::descriptor::lowest_layer_type]
+
+[indexterm2 asio.indexterm.posix__descriptor.lowest_layer_type..lowest_layer_type..posix::descriptor]
+A descriptor is always the lowest layer.
+
+
+ typedef descriptor lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.posix__descriptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.lowest_layer_type [*lowest_layer_type]]]
+ [A descriptor is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.native_handle_type [*native_handle_type]]]
+ [The native representation of a descriptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor.assign [*assign]]]
+ [Assign an existing native descriptor to the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.close [*close]]]
+ [Close the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.descriptor [*descriptor]]]
+ [Construct a descriptor without opening it.
+
+ Construct a descriptor on an existing native descriptor.
+
+ Move-construct a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.io_control [*io_control]]]
+ [Perform an IO control command on the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.is_open [*is_open]]]
+ [Determine whether the descriptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_handle [*native_handle]]]
+ [Get the native descriptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native descriptor implementation.
+
+ Sets the non-blocking mode of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the descriptor.
+
+ Sets the non-blocking mode of the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.operator_eq_ [*operator=]]]
+ [Move-assign a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.release [*release]]]
+ [Release ownership of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.wait [*wait]]]
+ [Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor._descriptor [*~descriptor]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.posix__descriptor `posix::descriptor`] class template provides the ability to wrap a POSIX descriptor.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle posix::descriptor::native_handle]
+
+[indexterm2 asio.indexterm.posix__descriptor.native_handle..native_handle..posix::descriptor]
+Get the native descriptor representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the descriptor. This is intended to allow access to native descriptor functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type posix::descriptor::native_handle_type]
+
+[indexterm2 asio.indexterm.posix__descriptor.native_handle_type..native_handle_type..posix::descriptor]
+The native representation of a descriptor.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking posix::descriptor::native_non_blocking]
+
+[indexterm2 asio.indexterm.posix__descriptor.native_non_blocking..native_non_blocking..posix::descriptor]
+Gets the non-blocking mode of the native descriptor implementation.
+
+
+ bool ``[link asio.reference.posix__descriptor.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void ``[link asio.reference.posix__descriptor.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 posix::descriptor::native_non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the native descriptor implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native descriptor. This mode has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying descriptor is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the descriptor object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native descriptor.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::native_non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native descriptor. It has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying descriptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::descriptor::native_non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native descriptor. It has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying descriptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking posix::descriptor::non_blocking]
+
+[indexterm2 asio.indexterm.posix__descriptor.non_blocking..non_blocking..posix::descriptor]
+Gets the non-blocking mode of the descriptor.
+
+
+ bool ``[link asio.reference.posix__descriptor.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void ``[link asio.reference.posix__descriptor.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.non_blocking.overload3 more...]]``
+
+
+[section:overload1 posix::descriptor::non_blocking (1 of 3 overloads)]
+
+
+Gets the non-blocking mode of the descriptor.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::non_blocking (2 of 3 overloads)]
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::descriptor::non_blocking (3 of 3 overloads)]
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq_ posix::descriptor::operator=]
+
+[indexterm2 asio.indexterm.posix__descriptor.operator_eq_..operator=..posix::descriptor]
+Move-assign a descriptor from another.
+
+
+ descriptor & operator=(
+ descriptor && other);
+
+
+This assignment operator moves a descriptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other descriptor object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `descriptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+
+[section:release posix::descriptor::release]
+
+[indexterm2 asio.indexterm.posix__descriptor.release..release..posix::descriptor]
+Release ownership of the native descriptor implementation.
+
+
+ native_handle_type release();
+
+
+This function may be used to obtain the underlying representation of the descriptor. After calling this function, `is_open()` returns false. The caller is responsible for closing the descriptor.
+
+All outstanding asynchronous read or write operations will finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[endsect]
+
+
+[section:wait posix::descriptor::wait]
+
+[indexterm2 asio.indexterm.posix__descriptor.wait..wait..posix::descriptor]
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.posix__descriptor.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.wait.overload1 more...]]``
+
+ void ``[link asio.reference.posix__descriptor.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__descriptor.wait.overload2 more...]]``
+
+
+[section:overload1 posix::descriptor::wait (1 of 2 overloads)]
+
+
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a descriptor to become readable.
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ descriptor.wait(asio::posix::stream_descriptor::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::descriptor::wait (2 of 2 overloads)]
+
+
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a descriptor to become readable.
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::error_code ec;
+ descriptor.wait(asio::posix::stream_descriptor::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type posix::descriptor::wait_type]
+
+[indexterm2 asio.indexterm.posix__descriptor.wait_type..wait_type..posix::descriptor]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.posix__descriptor.wait_type.wait_read..wait_read..posix::descriptor]
+[indexterm2 asio.indexterm.posix__descriptor.wait_type.wait_write..wait_write..posix::descriptor]
+[indexterm2 asio.indexterm.posix__descriptor.wait_type.wait_error..wait_error..posix::descriptor]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a descriptor to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a descriptor to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a descriptor to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `descriptor::wait()` and `descriptor::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_descriptor posix::descriptor::~descriptor]
+
+[indexterm2 asio.indexterm.posix__descriptor._descriptor..~descriptor..posix::descriptor]
+Protected destructor to prevent deletion through this type.
+
+
+ ~descriptor();
+
+
+This function destroys the descriptor, cancelling any outstanding asynchronous wait operations associated with the descriptor as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:posix__descriptor_base posix::descriptor_base]
+
+
+The [link asio.reference.posix__descriptor_base `posix::descriptor_base`] class is used as a base for the descriptor class as a place to define the associated IO control commands.
+
+
+ class descriptor_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.posix__descriptor_base.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor_base.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor_base._descriptor_base [*~descriptor_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:bytes_readable posix::descriptor_base::bytes_readable]
+
+[indexterm2 asio.indexterm.posix__descriptor_base.bytes_readable..bytes_readable..posix::descriptor_base]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::descriptor_base::bytes_readable command(true);
+ descriptor.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/descriptor_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:wait_type posix::descriptor_base::wait_type]
+
+[indexterm2 asio.indexterm.posix__descriptor_base.wait_type..wait_type..posix::descriptor_base]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.posix__descriptor_base.wait_type.wait_read..wait_read..posix::descriptor_base]
+[indexterm2 asio.indexterm.posix__descriptor_base.wait_type.wait_write..wait_write..posix::descriptor_base]
+[indexterm2 asio.indexterm.posix__descriptor_base.wait_type.wait_error..wait_error..posix::descriptor_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a descriptor to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a descriptor to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a descriptor to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `descriptor::wait()` and `descriptor::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_descriptor_base posix::descriptor_base::~descriptor_base]
+
+[indexterm2 asio.indexterm.posix__descriptor_base._descriptor_base..~descriptor_base..posix::descriptor_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~descriptor_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:posix__stream_descriptor posix::stream_descriptor]
+
+
+Provides stream-oriented descriptor functionality.
+
+
+ class stream_descriptor :
+ public posix::descriptor
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.posix__stream_descriptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__stream_descriptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__stream_descriptor.lowest_layer_type [*lowest_layer_type]]]
+ [A descriptor is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__stream_descriptor.native_handle_type [*native_handle_type]]]
+ [The native representation of a descriptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__stream_descriptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.assign [*assign]]]
+ [Assign an existing native descriptor to the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.close [*close]]]
+ [Close the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.io_control [*io_control]]]
+ [Perform an IO control command on the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.is_open [*is_open]]]
+ [Determine whether the descriptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.native_handle [*native_handle]]]
+ [Get the native descriptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native descriptor implementation.
+
+ Sets the non-blocking mode of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the descriptor.
+
+ Sets the non-blocking mode of the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.operator_eq_ [*operator=]]]
+ [Move-assign a stream_descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.read_some [*read_some]]]
+ [Read some data from the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.release [*release]]]
+ [Release ownership of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.stream_descriptor [*stream_descriptor]]]
+ [Construct a stream_descriptor without opening it.
+
+ Construct a stream_descriptor on an existing native descriptor.
+
+ Move-construct a stream_descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.wait [*wait]]]
+ [Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.posix__stream_descriptor.write_some [*write_some]]]
+ [Write some data to the descriptor. ]
+ ]
+
+]
+
+The [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] class template provides asynchronous and blocking stream-oriented descriptor functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/stream_descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign posix::stream_descriptor::assign]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.assign..assign..posix::stream_descriptor]
+Assign an existing native descriptor to the descriptor.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.assign.overload1 assign]``(
+ const native_handle_type & native_descriptor);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.assign.overload1 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.assign.overload2 assign]``(
+ const native_handle_type & native_descriptor,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.assign.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::assign (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Assign an existing native descriptor to the descriptor.
+
+
+ void assign(
+ const native_handle_type & native_descriptor);
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::assign (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Assign an existing native descriptor to the descriptor.
+
+
+ void assign(
+ const native_handle_type & native_descriptor,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_read_some posix::stream_descriptor::async_read_some]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.async_read_some..async_read_some..posix::stream_descriptor]
+Start an asynchronous read.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data from the stream descriptor. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The read operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ descriptor.async_read_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:async_wait posix::stream_descriptor::async_wait]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.async_wait..async_wait..posix::stream_descriptor]
+Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ wait_type w,
+ WaitHandler && handler);
+
+
+This function is used to perform an asynchronous wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+[[handler][The handler to be called when the wait operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Example]
+
+
+
+ void wait_handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Wait succeeded.
+ }
+ }
+
+ ...
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ descriptor.async_wait(
+ asio::posix::stream_descriptor::wait_read,
+ wait_handler);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some posix::stream_descriptor::async_write_some]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.async_write_some..async_write_some..posix::stream_descriptor]
+Start an asynchronous write.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write data to the stream descriptor. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the descriptor. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The write operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ descriptor.async_write_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:bytes_readable posix::stream_descriptor::bytes_readable]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.bytes_readable..bytes_readable..posix::stream_descriptor]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::descriptor_base::bytes_readable command(true);
+ descriptor.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/stream_descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:cancel posix::stream_descriptor::cancel]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.cancel..cancel..posix::stream_descriptor]
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.cancel.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::cancel (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::cancel (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Cancel all asynchronous operations associated with the descriptor.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close posix::stream_descriptor::close]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.close..close..posix::stream_descriptor]
+Close the descriptor.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.close.overload1 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.close.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::close (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Close the descriptor.
+
+
+ void close();
+
+
+This function is used to close the descriptor. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. Note that, even if the function indicates an error, the underlying descriptor is closed. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::close (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Close the descriptor.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the descriptor. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. Note that, even if the function indicates an error, the underlying descriptor is closed. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type posix::stream_descriptor::executor_type]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.executor_type..executor_type..posix::stream_descriptor]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/stream_descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor posix::stream_descriptor::get_executor]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.get_executor..get_executor..posix::stream_descriptor]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context posix::stream_descriptor::get_io_context]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.get_io_context..get_io_context..posix::stream_descriptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service posix::stream_descriptor::get_io_service]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.get_io_service..get_io_service..posix::stream_descriptor]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:io_control posix::stream_descriptor::io_control]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.io_control..io_control..posix::stream_descriptor]
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.posix__stream_descriptor.io_control.overload1 io_control]``(
+ IoControlCommand & command);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.io_control.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void ``[link asio.reference.posix__stream_descriptor.io_control.overload2 io_control]``(
+ IoControlCommand & command,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.io_control.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::io_control (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command);
+
+
+This function is used to execute an IO control command on the descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the descriptor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::posix::stream_descriptor::bytes_readable command;
+ descriptor.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::io_control (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Perform an IO control command on the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.IoControlCommand IoControlCommand]``>
+ void io_control(
+ IoControlCommand & command,
+ asio::error_code & ec);
+
+
+This function is used to execute an IO control command on the descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[command][The IO control command to be performed on the descriptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+[heading Example]
+
+Getting the number of bytes ready to read:
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::posix::stream_descriptor::bytes_readable command;
+ asio::error_code ec;
+ descriptor.io_control(command, ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open posix::stream_descriptor::is_open]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.is_open..is_open..posix::stream_descriptor]
+Determine whether the descriptor is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer posix::stream_descriptor::lowest_layer]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.lowest_layer..lowest_layer..posix::stream_descriptor]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.posix__stream_descriptor.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.posix__stream_descriptor.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a descriptor cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a descriptor cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type posix::stream_descriptor::lowest_layer_type]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.lowest_layer_type..lowest_layer_type..posix::stream_descriptor]
+A descriptor is always the lowest layer.
+
+
+ typedef descriptor lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.posix__descriptor.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.lowest_layer_type [*lowest_layer_type]]]
+ [A descriptor is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.native_handle_type [*native_handle_type]]]
+ [The native representation of a descriptor. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.posix__descriptor.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor.assign [*assign]]]
+ [Assign an existing native descriptor to the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.async_wait [*async_wait]]]
+ [Asynchronously wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.close [*close]]]
+ [Close the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.descriptor [*descriptor]]]
+ [Construct a descriptor without opening it.
+
+ Construct a descriptor on an existing native descriptor.
+
+ Move-construct a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.io_control [*io_control]]]
+ [Perform an IO control command on the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.is_open [*is_open]]]
+ [Determine whether the descriptor is open. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_handle [*native_handle]]]
+ [Get the native descriptor representation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.native_non_blocking [*native_non_blocking]]]
+ [Gets the non-blocking mode of the native descriptor implementation.
+
+ Sets the non-blocking mode of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.non_blocking [*non_blocking]]]
+ [Gets the non-blocking mode of the descriptor.
+
+ Sets the non-blocking mode of the descriptor. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.operator_eq_ [*operator=]]]
+ [Move-assign a descriptor from another. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.release [*release]]]
+ [Release ownership of the native descriptor implementation. ]
+ ]
+
+ [
+ [[link asio.reference.posix__descriptor.wait [*wait]]]
+ [Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.posix__descriptor._descriptor [*~descriptor]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.posix__descriptor `posix::descriptor`] class template provides the ability to wrap a POSIX descriptor.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/stream_descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle posix::stream_descriptor::native_handle]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.native_handle..native_handle..posix::stream_descriptor]
+Get the native descriptor representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the descriptor. This is intended to allow access to native descriptor functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type posix::stream_descriptor::native_handle_type]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.native_handle_type..native_handle_type..posix::stream_descriptor]
+The native representation of a descriptor.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/posix/stream_descriptor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:native_non_blocking posix::stream_descriptor::native_non_blocking]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.native_non_blocking..native_non_blocking..posix::stream_descriptor]
+Gets the non-blocking mode of the native descriptor implementation.
+
+
+ bool ``[link asio.reference.posix__stream_descriptor.native_non_blocking.overload1 native_non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.native_non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.native_non_blocking.overload2 native_non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.native_non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.native_non_blocking.overload3 native_non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.native_non_blocking.overload3 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::native_non_blocking (1 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Gets the non-blocking mode of the native descriptor implementation.
+
+
+ bool native_non_blocking() const;
+
+
+This function is used to retrieve the non-blocking mode of the underlying native descriptor. This mode has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Return Value]
+
+`true` if the underlying descriptor is in non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).
+
+
+[heading Remarks]
+
+The current non-blocking mode is cached by the descriptor object. Consequently, the return value may be incorrect if the non-blocking mode was set directly on the native descriptor.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::native_non_blocking (2 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void native_non_blocking(
+ bool mode);
+
+
+This function is used to modify the non-blocking mode of the underlying native descriptor. It has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying descriptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::stream_descriptor::native_non_blocking (3 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Sets the non-blocking mode of the native descriptor implementation.
+
+
+ void native_non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+This function is used to modify the non-blocking mode of the underlying native descriptor. It has no effect on the behaviour of the descriptor object's synchronous operations.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the underlying descriptor is put into non-blocking mode and direct system calls may fail with `asio::error::would_block` (or the equivalent system error).]]
+
+[[ec][Set to indicate what error occurred, if any. If the `mode` is `false`, but the current value of `non_blocking()` is `true`, this function fails with `asio::error::invalid_argument`, as the combination does not make sense. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:non_blocking posix::stream_descriptor::non_blocking]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.non_blocking..non_blocking..posix::stream_descriptor]
+Gets the non-blocking mode of the descriptor.
+
+
+ bool ``[link asio.reference.posix__stream_descriptor.non_blocking.overload1 non_blocking]``() const;
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.non_blocking.overload1 more...]]``
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.non_blocking.overload2 non_blocking]``(
+ bool mode);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.non_blocking.overload2 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.non_blocking.overload3 non_blocking]``(
+ bool mode,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.non_blocking.overload3 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::non_blocking (1 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Gets the non-blocking mode of the descriptor.
+
+
+ bool non_blocking() const;
+
+
+
+[heading Return Value]
+
+`true` if the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::non_blocking (2 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void non_blocking(
+ bool mode);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::stream_descriptor::non_blocking (3 of 3 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Sets the non-blocking mode of the descriptor.
+
+
+ void non_blocking(
+ bool mode,
+ asio::error_code & ec);
+
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[mode][If `true`, the descriptor's synchronous operations will fail with `asio::error::would_block` if they are unable to perform the requested operation immediately. If `false`, synchronous operations will block until complete.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+The non-blocking mode has no effect on the behaviour of asynchronous operations. Asynchronous operations will never fail with the error `asio::error::would_block`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq_ posix::stream_descriptor::operator=]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.operator_eq_..operator=..posix::stream_descriptor]
+Move-assign a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] from another.
+
+
+ stream_descriptor & operator=(
+ stream_descriptor && other);
+
+
+This assignment operator moves a stream descriptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `stream_descriptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[section:read_some posix::stream_descriptor::read_some]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.read_some..read_some..posix::stream_descriptor]
+Read some data from the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.posix__stream_descriptor.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.read_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.posix__stream_descriptor.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.read_some.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::read_some (1 of 2 overloads)]
+
+
+Read some data from the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the stream descriptor. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ descriptor.read_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::read_some (2 of 2 overloads)]
+
+
+Read some data from the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the stream descriptor. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:release posix::stream_descriptor::release]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.release..release..posix::stream_descriptor]
+Release ownership of the native descriptor implementation.
+
+
+ native_handle_type release();
+
+
+This function may be used to obtain the underlying representation of the descriptor. After calling this function, `is_open()` returns false. The caller is responsible for closing the descriptor.
+
+All outstanding asynchronous read or write operations will finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[endsect]
+
+
+[section:stream_descriptor posix::stream_descriptor::stream_descriptor]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.stream_descriptor..stream_descriptor..posix::stream_descriptor]
+Construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] without opening it.
+
+
+ explicit ``[link asio.reference.posix__stream_descriptor.stream_descriptor.overload1 stream_descriptor]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.stream_descriptor.overload1 more...]]``
+
+
+Construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] on an existing native descriptor.
+
+
+ ``[link asio.reference.posix__stream_descriptor.stream_descriptor.overload2 stream_descriptor]``(
+ asio::io_context & io_context,
+ const native_handle_type & native_descriptor);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.stream_descriptor.overload2 more...]]``
+
+
+Move-construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] from another.
+
+
+ ``[link asio.reference.posix__stream_descriptor.stream_descriptor.overload3 stream_descriptor]``(
+ stream_descriptor && other);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.stream_descriptor.overload3 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::stream_descriptor (1 of 3 overloads)]
+
+
+Construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] without opening it.
+
+
+ stream_descriptor(
+ asio::io_context & io_context);
+
+
+This constructor creates a stream descriptor without opening it. The descriptor needs to be opened and then connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream descriptor will use to dispatch handlers for any asynchronous operations performed on the descriptor. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::stream_descriptor (2 of 3 overloads)]
+
+
+Construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] on an existing native descriptor.
+
+
+ stream_descriptor(
+ asio::io_context & io_context,
+ const native_handle_type & native_descriptor);
+
+
+This constructor creates a stream descriptor object to hold an existing native descriptor.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream descriptor will use to dispatch handlers for any asynchronous operations performed on the descriptor.]]
+
+[[native_descriptor][The new underlying descriptor implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 posix::stream_descriptor::stream_descriptor (3 of 3 overloads)]
+
+
+Move-construct a [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] from another.
+
+
+ stream_descriptor(
+ stream_descriptor && other);
+
+
+This constructor moves a stream descriptor from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.posix__stream_descriptor `posix::stream_descriptor`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `stream_descriptor(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:wait posix::stream_descriptor::wait]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.wait..wait..posix::stream_descriptor]
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void ``[link asio.reference.posix__stream_descriptor.wait.overload1 wait]``(
+ wait_type w);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.wait.overload1 more...]]``
+
+ void ``[link asio.reference.posix__stream_descriptor.wait.overload2 wait]``(
+ wait_type w,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.wait.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::wait (1 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w);
+
+
+This function is used to perform a blocking wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a descriptor to become readable.
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ descriptor.wait(asio::posix::stream_descriptor::wait_read);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::wait (2 of 2 overloads)]
+
+
+['Inherited from posix::descriptor.]
+
+
+Wait for the descriptor to become ready to read, ready to write, or to have pending error conditions.
+
+
+ void wait(
+ wait_type w,
+ asio::error_code & ec);
+
+
+This function is used to perform a blocking wait for a descriptor to enter a ready to read, write or error condition state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[w][Specifies the desired descriptor state.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Example]
+
+Waiting for a descriptor to become readable.
+
+ asio::posix::stream_descriptor descriptor(io_context);
+ ...
+ asio::error_code ec;
+ descriptor.wait(asio::posix::stream_descriptor::wait_read, ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:wait_type posix::stream_descriptor::wait_type]
+
+
+['Inherited from posix::descriptor.]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.wait_type..wait_type..posix::stream_descriptor]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.wait_type.wait_read..wait_read..posix::stream_descriptor]
+[indexterm2 asio.indexterm.posix__stream_descriptor.wait_type.wait_write..wait_write..posix::stream_descriptor]
+[indexterm2 asio.indexterm.posix__stream_descriptor.wait_type.wait_error..wait_error..posix::stream_descriptor]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a descriptor to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a descriptor to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a descriptor to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `descriptor::wait()` and `descriptor::async_wait()`.
+
+
+[endsect]
+
+
+[section:write_some posix::stream_descriptor::write_some]
+
+[indexterm2 asio.indexterm.posix__stream_descriptor.write_some..write_some..posix::stream_descriptor]
+Write some data to the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.posix__stream_descriptor.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.write_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.posix__stream_descriptor.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.posix__stream_descriptor.write_some.overload2 more...]]``
+
+
+[section:overload1 posix::stream_descriptor::write_some (1 of 2 overloads)]
+
+
+Write some data to the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data to the stream descriptor. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the descriptor.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ descriptor.write_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 posix::stream_descriptor::write_some (2 of 2 overloads)]
+
+
+Write some data to the descriptor.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data to the stream descriptor. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the descriptor.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:post post]
+
+[indexterm1 asio.indexterm.post..post]
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.post.overload1 post]``(
+ CompletionToken && token);
+ `` [''''&raquo;''' [link asio.reference.post.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.post.overload2 post]``(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.post.overload2 more...]]``
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.post.overload3 post]``(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.post.overload3 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/post.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 post (1 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` post(
+ CompletionToken && token);
+
+
+This function submits an object for execution using the object's associated executor. The function object is queued for execution, and is never called from the current thread prior to returning from `post()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex` by performing `get_associated_executor(handler)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Performs `ex.post(std::move(handler), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 post (2 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` post(
+ const Executor & ex,
+ CompletionToken && token,
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+This function submits an object for execution using the specified executor. The function object is queued for execution, and is never called from the current thread prior to returning from `post()`.
+
+This function has the following effects:
+
+
+* Constructs a function object handler of type `Handler`, initialized with `handler(forward<CompletionToken>(token))`.
+
+
+* Constructs an object `result` of type `async_result<Handler>`, initializing the object as `result(handler)`.
+
+
+* Obtains the handler's associated executor object `ex1` by performing `get_associated_executor(handler)`.
+
+
+* Creates a work object `w` by performing `make_work(ex1)`.
+
+
+* Obtains the handler's associated allocator object `alloc` by performing `get_associated_allocator(handler)`.
+
+
+* Constructs a function object `f` with a function call operator that performs `ex1.dispatch(std::move(handler), alloc)` followed by `w.reset()`.
+
+
+* Performs `Executor(ex).post(std::move(f), alloc)`.
+
+
+* Returns `result.get()`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 post (3 of 3 overloads)]
+
+
+Submits a completion token or function object for execution.
+
+
+ template<
+ typename ExecutionContext,
+ typename CompletionToken>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` post(
+ ExecutionContext & ctx,
+ CompletionToken && token,
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+
+[heading Return Value]
+
+`post(ctx.get_executor(), forward<CompletionToken>(token))`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read read]
+
+[indexterm1 asio.indexterm.read..read]
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.read.overload1 read]``(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.read.overload2 read]``(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload3 read]``(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload4 read]``(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read.overload5 read]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read.overload6 read]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload7 read]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload8 read]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read.overload8 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read.overload9 read]``(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b);
+ `` [''''&raquo;''' [link asio.reference.read.overload9 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read.overload10 read]``(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read.overload10 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload11 read]``(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.read.overload11 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read.overload12 read]``(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read.overload12 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 read (1 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read(s, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 read (2 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read(s, asio::buffer(data, size), ec);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 read (3 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read(s, asio::buffer(data, size),
+ asio::transfer_at_least(32));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 read (4 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the stream.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 read (5 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The specified dynamic buffer sequence is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 read (6 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 read (7 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The specified dynamic buffer sequence is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 read (8 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The specified dynamic buffer sequence is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 read (9 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, b,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 read (10 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read(
+ s, b,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 read (11 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 read (12 of 12 overloads)]
+
+
+Attempt to read a certain amount of data from a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read(
+ SyncReadStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
+
+
+* The supplied buffer is full (that is, it has reached maximum size).
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_at read_at]
+
+[indexterm1 asio.indexterm.read_at..read_at]
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.read_at.overload1 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.read_at.overload2 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read_at.overload3 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read_at.overload4 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_at.overload5 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_at.overload6 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read_at.overload7 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.read_at.overload8 read_at]``(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_at.overload8 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read_at.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 read_at (1 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read_at(d, 42, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read_at(
+ d, 42, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 read_at (2 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read_at(d, 42,
+ asio::buffer(data, size), ec);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read_at(
+ d, 42, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 read_at (3 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's read\_some\_at function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::read_at(d, 42, asio::buffer(data, size),
+ asio::transfer_at_least(32));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 read_at (4 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. The sum of the buffer sizes indicates the maximum number of bytes to read from the device.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's read\_some\_at function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 read_at (5 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read_at(
+ d, 42, b,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 read_at (6 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::read_at(
+ d, 42, b,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 read_at (7 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's read\_some\_at function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 read_at (8 of 8 overloads)]
+
+
+Attempt to read a certain amount of data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessReadDevice SyncRandomAccessReadDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t read_at(
+ SyncRandomAccessReadDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device from which the data is to be read. The type must support the SyncRandomAccessReadDevice concept.]]
+
+[[offset][The offset at which the data will be read.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object into which the data will be read.]]
+
+[[completion_condition][The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest read_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the device's read\_some\_at function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_until read_until]
+
+[indexterm1 asio.indexterm.read_until..read_until]
+Read data into a dynamic buffer sequence, or into a streambuf, until it contains a delimiter, matches a regular expression, or a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload1 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload2 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload3 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload4 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload5 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.read_until.overload6 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition>
+ std::size_t ``[link asio.reference.read_until.overload7 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition>
+ std::size_t ``[link asio.reference.read_until.overload8 read_until]``(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ asio::error_code & ec,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload8 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload9 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload9 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload10 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload10 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload11 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload11 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload12 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload12 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload13 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload13 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.read_until.overload14 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload14 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition>
+ std::size_t ``[link asio.reference.read_until.overload15 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload15 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition>
+ std::size_t ``[link asio.reference.read_until.overload16 read_until]``(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ asio::error_code & ec,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.read_until.overload16 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/read_until.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 read_until (1 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[delim][The delimiter character.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the delimiter.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a `std::string` until a newline is encountered:
+
+ std::string data;
+ std::string n = asio::read_until(s,
+ asio::dynamic_buffer(data), '\n');
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+
+
+After the `read_until` operation completes successfully, the string `data` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 read_until (2 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ char delim,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[delim][The delimiter character.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the delimiter. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 read_until (3 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[delim][The delimiter string.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the delimiter.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a `std::string` until a CR-LF sequence is encountered:
+
+ std::string data;
+ std::string n = asio::read_until(s,
+ asio::dynamic_buffer(data), "\r\n");
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+
+
+After the `read_until` operation completes successfully, the string `data` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 read_until (4 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ string_view delim,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the dynamic buffer sequence contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][The dynamic buffer sequence into which the data will be read.]]
+
+[[delim][The delimiter string.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the delimiter. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond the delimiter. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 read_until (5 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until some part of the data it contains matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains some data that matches a regular expression. The call will block until one of the following conditions is true:
+
+
+* A substring of the dynamic buffer sequence's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains data that matches the regular expression, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][A dynamic buffer sequence into which the data will be read.]]
+
+[[expr][The regular expression.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the substring that matches the regular expression.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a `std::string` until a CR-LF sequence is encountered:
+
+ std::string data;
+ std::string n = asio::read_until(s,
+ asio::dynamic_buffer(data), boost::regex("\r\n"));
+ std::string line = data.substr(0, n);
+ data.erase(0, n);
+
+
+After the `read_until` operation completes successfully, the string `data` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `substr` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+After the call to `erase`, the remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 read_until (6 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until some part of the data it contains matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ const boost::regex & expr,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified dynamic buffer sequence until the dynamic buffer sequence's get area contains some data that matches a regular expression. The call will block until one of the following conditions is true:
+
+
+* A substring of the dynamic buffer sequence's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the dynamic buffer sequence's get area already contains data that matches the regular expression, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][A dynamic buffer sequence into which the data will be read.]]
+
+[[expr][The regular expression.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area up to and including the substring that matches the regular expression. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 read_until (7 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to read data into the specified dynamic buffer sequence until a user-defined match condition function object, when applied to the data contained in the dynamic buffer sequence, indicates a successful match. The call will block until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the match condition function object already indicates a match, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][A dynamic buffer sequence into which the data will be read.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<typename DynamicBuffer::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic\_buffer's get area that have been fully consumed by the match function.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the function object. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+[heading Examples]
+
+To read data into a dynamic buffer sequence until whitespace is encountered:
+
+ typedef asio::buffers_iterator<
+ asio::const_buffers_1> iterator;
+
+ std::pair<iterator, bool>
+ match_whitespace(iterator begin, iterator end)
+ {
+ iterator i = begin;
+ while (i != end)
+ if (std::isspace(*i++))
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+ ...
+ std::string data;
+ asio::read_until(s, data, match_whitespace);
+
+
+
+
+To read data into a `std::string` until a matching character is found:
+
+ class match_char
+ {
+ public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+ private:
+ char c_;
+ };
+
+ namespace asio {
+ template <> struct is_match_condition<match_char>
+ : public boost::true_type {};
+ } // namespace asio
+ ...
+ std::string data;
+ asio::read_until(s, data, match_char('a'));
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 read_until (8 of 16 overloads)]
+
+
+Read data into a dynamic buffer sequence until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename MatchCondition>
+ std::size_t read_until(
+ SyncReadStream & s,
+ DynamicBuffer && buffers,
+ MatchCondition match_condition,
+ asio::error_code & ec,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to read data into the specified dynamic buffer sequence until a user-defined match condition function object, when applied to the data contained in the dynamic buffer sequence, indicates a successful match. The call will block until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the match condition function object already indicates a match, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[buffers][A dynamic buffer sequence into which the data will be read.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<DynamicBuffer::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the dynamic buffer sequence's get area that have been fully consumed by the match function. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the dynamic buffer sequence may contain additional data beyond that which matched the function object. An application will typically leave that data in the dynamic buffer sequence for a subsequent read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 read_until (9 of 16 overloads)]
+
+
+Read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[delim][The delimiter character.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the delimiter.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a streambuf until a newline is encountered:
+
+ asio::streambuf b;
+ asio::read_until(s, b, '\n');
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+
+
+After the `read_until` operation completes successfully, the buffer `b` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 read_until (10 of 16 overloads)]
+
+
+Read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ char delim,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[delim][The delimiter character.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the delimiter. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 read_until (11 of 16 overloads)]
+
+
+Read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[delim][The delimiter string.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the delimiter.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a streambuf until a newline is encountered:
+
+ asio::streambuf b;
+ asio::read_until(s, b, "\r\n");
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+
+
+After the `read_until` operation completes successfully, the buffer `b` contains the delimiter:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the delimiter, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 read_until (12 of 16 overloads)]
+
+
+Read data into a streambuf until it contains a specified delimiter.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ string_view delim,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter. The call will block until one of the following conditions is true:
+
+
+* The get area of the streambuf contains the specified delimiter.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains the delimiter, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[delim][The delimiter string.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the delimiter. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload13 read_until (13 of 16 overloads)]
+
+
+Read data into a streambuf until some part of the data it contains matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains some data that matches a regular expression. The call will block until one of the following conditions is true:
+
+
+* A substring of the streambuf's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains data that matches the regular expression, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[expr][The regular expression.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the substring that matches the regular expression.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+[heading Example]
+
+To read data into a streambuf until a CR-LF sequence is encountered:
+
+ asio::streambuf b;
+ asio::read_until(s, b, boost::regex("\r\n"));
+ std::istream is(&b);
+ std::string line;
+ std::getline(is, line);
+
+
+After the `read_until` operation completes successfully, the buffer `b` contains the data which matched the regular expression:
+
+ { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... }
+
+
+The call to `std::getline` then extracts the data up to and including the match, so that the string `line` contains:
+
+ { 'a', 'b', ..., 'c', '\r', '\n' }
+
+
+The remaining data is left in the buffer `b` as follows:
+
+ { 'd', 'e', ... }
+
+
+This data may be the start of a new line, to be extracted by a subsequent `read_until` operation.
+
+
+
+
+[endsect]
+
+
+
+[section:overload14 read_until (14 of 16 overloads)]
+
+
+Read data into a streambuf until some part of the data it contains matches a regular expression.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ const boost::regex & expr,
+ asio::error_code & ec);
+
+
+This function is used to read data into the specified streambuf until the streambuf's get area contains some data that matches a regular expression. The call will block until one of the following conditions is true:
+
+
+* A substring of the streambuf's get area matches the regular expression.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the streambuf's get area already contains data that matches the regular expression, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[expr][The regular expression.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area up to and including the substring that matches the regular expression. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond that which matched the regular expression. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+
+
+
+[endsect]
+
+
+
+[section:overload15 read_until (15 of 16 overloads)]
+
+
+Read data into a streambuf until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to read data into the specified streambuf until a user-defined match condition function object, when applied to the data contained in the streambuf, indicates a successful match. The call will block until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the match condition function object already indicates a match, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area that have been fully consumed by the match function.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond that which matched the function object. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+[heading Examples]
+
+To read data into a streambuf until whitespace is encountered:
+
+ typedef asio::buffers_iterator<
+ asio::streambuf::const_buffers_type> iterator;
+
+ std::pair<iterator, bool>
+ match_whitespace(iterator begin, iterator end)
+ {
+ iterator i = begin;
+ while (i != end)
+ if (std::isspace(*i++))
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+ ...
+ asio::streambuf b;
+ asio::read_until(s, b, match_whitespace);
+
+
+
+
+To read data into a streambuf until a matching character is found:
+
+ class match_char
+ {
+ public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+ private:
+ char c_;
+ };
+
+ namespace asio {
+ template <> struct is_match_condition<match_char>
+ : public boost::true_type {};
+ } // namespace asio
+ ...
+ asio::streambuf b;
+ asio::read_until(s, b, match_char('a'));
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload16 read_until (16 of 16 overloads)]
+
+
+Read data into a streambuf until a function object indicates a match.
+
+
+ template<
+ typename ``[link asio.reference.SyncReadStream SyncReadStream]``,
+ typename Allocator,
+ typename MatchCondition>
+ std::size_t read_until(
+ SyncReadStream & s,
+ asio::basic_streambuf< Allocator > & b,
+ MatchCondition match_condition,
+ asio::error_code & ec,
+ typename enable_if< is_match_condition< MatchCondition >::value >::type * = 0);
+
+
+This function is used to read data into the specified streambuf until a user-defined match condition function object, when applied to the data contained in the streambuf, indicates a successful match. The call will block until one of the following conditions is true:
+
+
+* The match condition function object returns a std::pair where the second element evaluates to true.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's read\_some function. If the match condition function object already indicates a match, the function returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream from which the data is to be read. The type must support the SyncReadStream concept.]]
+
+[[b][A streambuf object into which the data will be read.]]
+
+[[match_condition][The function object to be called to determine whether a match exists. The signature of the function object must be:
+``
+ pair<iterator, bool> match_condition(iterator begin, iterator end);
+``
+where `iterator` represents the type:
+``
+ buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
+``
+The iterator parameters `begin` and `end` define the range of bytes to be scanned to determine whether there is a match. The `first` member of the return value is an iterator marking one-past-the-end of the bytes that have been consumed by the match function. This iterator is used to calculate the `begin` parameter for any subsequent invocation of the match condition. The `second` member of the return value is true if a match has been found, false otherwise.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes in the streambuf's get area that have been fully consumed by the match function. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+After a successful read\_until operation, the streambuf may contain additional data beyond that which matched the function object. An application will typically leave that data in the streambuf for a subsequent read\_until operation to examine.
+
+The default implementation of the `is_match_condition` type trait evaluates to true for function pointers and function objects with a `result_type` typedef. It must be specialised for other user-defined function objects.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:serial_port serial_port]
+
+
+Provides serial port functionality.
+
+
+ class serial_port :
+ public serial_port_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_serial_port is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port.native_handle_type [*native_handle_type]]]
+ [The native representation of a serial port. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port.assign [*assign]]]
+ [Assign an existing native serial port to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.close [*close]]]
+ [Close the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_option [*get_option]]]
+ [Get an option from the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.is_open [*is_open]]]
+ [Determine whether the serial port is open. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.native_handle [*native_handle]]]
+ [Get the native serial port representation. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.open [*open]]]
+ [Open the serial port using the specified device name. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.operator_eq_ [*operator=]]]
+ [Move-assign a serial_port from another. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.read_some [*read_some]]]
+ [Read some data from the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.send_break [*send_break]]]
+ [Send a break sequence to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.serial_port [*serial_port]]]
+ [Construct a serial_port without opening it.
+
+ Construct and open a serial_port.
+
+ Construct a serial_port on an existing native serial port.
+
+ Move-construct a serial_port from another. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.set_option [*set_option]]]
+ [Set an option on the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.write_some [*write_some]]]
+ [Write some data to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port._serial_port [*~serial_port]]]
+ [Destroys the serial port. ]
+ ]
+
+]
+
+The [link asio.reference.serial_port `serial_port`] class provides a wrapper over serial port functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign serial_port::assign]
+
+[indexterm2 asio.indexterm.serial_port.assign..assign..serial_port]
+Assign an existing native serial port to the serial port.
+
+
+ void ``[link asio.reference.serial_port.assign.overload1 assign]``(
+ const native_handle_type & native_serial_port);
+ `` [''''&raquo;''' [link asio.reference.serial_port.assign.overload1 more...]]``
+
+ void ``[link asio.reference.serial_port.assign.overload2 assign]``(
+ const native_handle_type & native_serial_port,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.assign.overload2 more...]]``
+
+
+[section:overload1 serial_port::assign (1 of 2 overloads)]
+
+
+Assign an existing native serial port to the serial port.
+
+
+ void assign(
+ const native_handle_type & native_serial_port);
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::assign (2 of 2 overloads)]
+
+
+Assign an existing native serial port to the serial port.
+
+
+ void assign(
+ const native_handle_type & native_serial_port,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_read_some serial_port::async_read_some]
+
+[indexterm2 asio.indexterm.serial_port.async_read_some..async_read_some..serial_port]
+Start an asynchronous read.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data from the serial port. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The read operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ serial_port.async_read_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some serial_port::async_write_some]
+
+[indexterm2 asio.indexterm.serial_port.async_write_some..async_write_some..serial_port]
+Start an asynchronous write.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write data to the serial port. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the serial port. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The write operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ serial_port.async_write_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[section:cancel serial_port::cancel]
+
+[indexterm2 asio.indexterm.serial_port.cancel..cancel..serial_port]
+Cancel all asynchronous operations associated with the serial port.
+
+
+ void ``[link asio.reference.serial_port.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.serial_port.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.serial_port.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.cancel.overload2 more...]]``
+
+
+[section:overload1 serial_port::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the serial port.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the serial port.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close serial_port::close]
+
+[indexterm2 asio.indexterm.serial_port.close..close..serial_port]
+Close the serial port.
+
+
+ void ``[link asio.reference.serial_port.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.serial_port.close.overload1 more...]]``
+
+ void ``[link asio.reference.serial_port.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.close.overload2 more...]]``
+
+
+[section:overload1 serial_port::close (1 of 2 overloads)]
+
+
+Close the serial port.
+
+
+ void close();
+
+
+This function is used to close the serial port. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::close (2 of 2 overloads)]
+
+
+Close the serial port.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the serial port. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type serial_port::executor_type]
+
+[indexterm2 asio.indexterm.serial_port.executor_type..executor_type..serial_port]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor serial_port::get_executor]
+
+[indexterm2 asio.indexterm.serial_port.get_executor..get_executor..serial_port]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context serial_port::get_io_context]
+
+[indexterm2 asio.indexterm.serial_port.get_io_context..get_io_context..serial_port]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service serial_port::get_io_service]
+
+[indexterm2 asio.indexterm.serial_port.get_io_service..get_io_service..serial_port]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:get_option serial_port::get_option]
+
+[indexterm2 asio.indexterm.serial_port.get_option..get_option..serial_port]
+Get an option from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.GettableSerialPortOption GettableSerialPortOption]``>
+ void ``[link asio.reference.serial_port.get_option.overload1 get_option]``(
+ GettableSerialPortOption & option);
+ `` [''''&raquo;''' [link asio.reference.serial_port.get_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.GettableSerialPortOption GettableSerialPortOption]``>
+ void ``[link asio.reference.serial_port.get_option.overload2 get_option]``(
+ GettableSerialPortOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.get_option.overload2 more...]]``
+
+
+[section:overload1 serial_port::get_option (1 of 2 overloads)]
+
+
+Get an option from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.GettableSerialPortOption GettableSerialPortOption]``>
+ void get_option(
+ GettableSerialPortOption & option);
+
+
+This function is used to get the current value of an option on the serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the serial port.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::get_option (2 of 2 overloads)]
+
+
+Get an option from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.GettableSerialPortOption GettableSerialPortOption]``>
+ void get_option(
+ GettableSerialPortOption & option,
+ asio::error_code & ec);
+
+
+This function is used to get the current value of an option on the serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be obtained from the serial port.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:is_open serial_port::is_open]
+
+[indexterm2 asio.indexterm.serial_port.is_open..is_open..serial_port]
+Determine whether the serial port is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer serial_port::lowest_layer]
+
+[indexterm2 asio.indexterm.serial_port.lowest_layer..lowest_layer..serial_port]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.serial_port.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.serial_port.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.serial_port.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.serial_port.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 serial_port::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since a [link asio.reference.serial_port `serial_port`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since a [link asio.reference.serial_port `serial_port`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type serial_port::lowest_layer_type]
+
+[indexterm2 asio.indexterm.serial_port.lowest_layer_type..lowest_layer_type..serial_port]
+A basic\_serial\_port is always the lowest layer.
+
+
+ typedef serial_port lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port.lowest_layer_type [*lowest_layer_type]]]
+ [A basic_serial_port is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port.native_handle_type [*native_handle_type]]]
+ [The native representation of a serial port. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port.assign [*assign]]]
+ [Assign an existing native serial port to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.close [*close]]]
+ [Close the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.get_option [*get_option]]]
+ [Get an option from the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.is_open [*is_open]]]
+ [Determine whether the serial port is open. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.native_handle [*native_handle]]]
+ [Get the native serial port representation. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.open [*open]]]
+ [Open the serial port using the specified device name. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.operator_eq_ [*operator=]]]
+ [Move-assign a serial_port from another. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.read_some [*read_some]]]
+ [Read some data from the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.send_break [*send_break]]]
+ [Send a break sequence to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.serial_port [*serial_port]]]
+ [Construct a serial_port without opening it.
+
+ Construct and open a serial_port.
+
+ Construct a serial_port on an existing native serial port.
+
+ Move-construct a serial_port from another. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.set_option [*set_option]]]
+ [Set an option on the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port.write_some [*write_some]]]
+ [Write some data to the serial port. ]
+ ]
+
+ [
+ [[link asio.reference.serial_port._serial_port [*~serial_port]]]
+ [Destroys the serial port. ]
+ ]
+
+]
+
+The [link asio.reference.serial_port `serial_port`] class provides a wrapper over serial port functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle serial_port::native_handle]
+
+[indexterm2 asio.indexterm.serial_port.native_handle..native_handle..serial_port]
+Get the native serial port representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the serial port. This is intended to allow access to native serial port functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type serial_port::native_handle_type]
+
+[indexterm2 asio.indexterm.serial_port.native_handle_type..native_handle_type..serial_port]
+The native representation of a serial port.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:open serial_port::open]
+
+[indexterm2 asio.indexterm.serial_port.open..open..serial_port]
+Open the serial port using the specified device name.
+
+
+ void ``[link asio.reference.serial_port.open.overload1 open]``(
+ const std::string & device);
+ `` [''''&raquo;''' [link asio.reference.serial_port.open.overload1 more...]]``
+
+ void ``[link asio.reference.serial_port.open.overload2 open]``(
+ const std::string & device,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.open.overload2 more...]]``
+
+
+[section:overload1 serial_port::open (1 of 2 overloads)]
+
+
+Open the serial port using the specified device name.
+
+
+ void open(
+ const std::string & device);
+
+
+This function opens the serial port for the specified device name.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[device][The platform-specific device name.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::open (2 of 2 overloads)]
+
+
+Open the serial port using the specified device name.
+
+
+ void open(
+ const std::string & device,
+ asio::error_code & ec);
+
+
+This function opens the serial port using the given platform-specific device name.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[device][The platform-specific device name.]]
+
+[[ec][Set the indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq_ serial_port::operator=]
+
+[indexterm2 asio.indexterm.serial_port.operator_eq_..operator=..serial_port]
+Move-assign a [link asio.reference.serial_port `serial_port`] from another.
+
+
+ serial_port & operator=(
+ serial_port && other);
+
+
+This assignment operator moves a serial port from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.serial_port `serial_port`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `serial_port(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[section:read_some serial_port::read_some]
+
+[indexterm2 asio.indexterm.serial_port.read_some..read_some..serial_port]
+Read some data from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.serial_port.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.serial_port.read_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.serial_port.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.read_some.overload2 more...]]``
+
+
+[section:overload1 serial_port::read_some (1 of 2 overloads)]
+
+
+Read some data from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the serial port. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ serial_port.read_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::read_some (2 of 2 overloads)]
+
+
+Read some data from the serial port.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the serial port. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:send_break serial_port::send_break]
+
+[indexterm2 asio.indexterm.serial_port.send_break..send_break..serial_port]
+Send a break sequence to the serial port.
+
+
+ void ``[link asio.reference.serial_port.send_break.overload1 send_break]``();
+ `` [''''&raquo;''' [link asio.reference.serial_port.send_break.overload1 more...]]``
+
+ void ``[link asio.reference.serial_port.send_break.overload2 send_break]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.send_break.overload2 more...]]``
+
+
+[section:overload1 serial_port::send_break (1 of 2 overloads)]
+
+
+Send a break sequence to the serial port.
+
+
+ void send_break();
+
+
+This function causes a break sequence of platform-specific duration to be sent out the serial port.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::send_break (2 of 2 overloads)]
+
+
+Send a break sequence to the serial port.
+
+
+ void send_break(
+ asio::error_code & ec);
+
+
+This function causes a break sequence of platform-specific duration to be sent out the serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:serial_port serial_port::serial_port]
+
+[indexterm2 asio.indexterm.serial_port.serial_port..serial_port..serial_port]
+Construct a [link asio.reference.serial_port `serial_port`] without opening it.
+
+
+ explicit ``[link asio.reference.serial_port.serial_port.overload1 serial_port]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.serial_port.serial_port.overload1 more...]]``
+
+
+Construct and open a [link asio.reference.serial_port `serial_port`].
+
+
+ explicit ``[link asio.reference.serial_port.serial_port.overload2 serial_port]``(
+ asio::io_context & io_context,
+ const char * device);
+ `` [''''&raquo;''' [link asio.reference.serial_port.serial_port.overload2 more...]]``
+
+ explicit ``[link asio.reference.serial_port.serial_port.overload3 serial_port]``(
+ asio::io_context & io_context,
+ const std::string & device);
+ `` [''''&raquo;''' [link asio.reference.serial_port.serial_port.overload3 more...]]``
+
+
+Construct a [link asio.reference.serial_port `serial_port`] on an existing native serial port.
+
+
+ ``[link asio.reference.serial_port.serial_port.overload4 serial_port]``(
+ asio::io_context & io_context,
+ const native_handle_type & native_serial_port);
+ `` [''''&raquo;''' [link asio.reference.serial_port.serial_port.overload4 more...]]``
+
+
+Move-construct a [link asio.reference.serial_port `serial_port`] from another.
+
+
+ ``[link asio.reference.serial_port.serial_port.overload5 serial_port]``(
+ serial_port && other);
+ `` [''''&raquo;''' [link asio.reference.serial_port.serial_port.overload5 more...]]``
+
+
+[section:overload1 serial_port::serial_port (1 of 5 overloads)]
+
+
+Construct a [link asio.reference.serial_port `serial_port`] without opening it.
+
+
+ serial_port(
+ asio::io_context & io_context);
+
+
+This constructor creates a serial port without opening it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the serial port will use to dispatch handlers for any asynchronous operations performed on the port. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::serial_port (2 of 5 overloads)]
+
+
+Construct and open a [link asio.reference.serial_port `serial_port`].
+
+
+ serial_port(
+ asio::io_context & io_context,
+ const char * device);
+
+
+This constructor creates and opens a serial port for the specified device name.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the serial port will use to dispatch handlers for any asynchronous operations performed on the port.]]
+
+[[device][The platform-specific device name for this serial port. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 serial_port::serial_port (3 of 5 overloads)]
+
+
+Construct and open a [link asio.reference.serial_port `serial_port`].
+
+
+ serial_port(
+ asio::io_context & io_context,
+ const std::string & device);
+
+
+This constructor creates and opens a serial port for the specified device name.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the serial port will use to dispatch handlers for any asynchronous operations performed on the port.]]
+
+[[device][The platform-specific device name for this serial port. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 serial_port::serial_port (4 of 5 overloads)]
+
+
+Construct a [link asio.reference.serial_port `serial_port`] on an existing native serial port.
+
+
+ serial_port(
+ asio::io_context & io_context,
+ const native_handle_type & native_serial_port);
+
+
+This constructor creates a serial port object to hold an existing native serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the serial port will use to dispatch handlers for any asynchronous operations performed on the port.]]
+
+[[native_serial_port][A native serial port.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 serial_port::serial_port (5 of 5 overloads)]
+
+
+Move-construct a [link asio.reference.serial_port `serial_port`] from another.
+
+
+ serial_port(
+ serial_port && other);
+
+
+This constructor moves a serial port from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.serial_port `serial_port`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `serial_port(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_option serial_port::set_option]
+
+[indexterm2 asio.indexterm.serial_port.set_option..set_option..serial_port]
+Set an option on the serial port.
+
+
+ template<
+ typename ``[link asio.reference.SettableSerialPortOption SettableSerialPortOption]``>
+ void ``[link asio.reference.serial_port.set_option.overload1 set_option]``(
+ const SettableSerialPortOption & option);
+ `` [''''&raquo;''' [link asio.reference.serial_port.set_option.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SettableSerialPortOption SettableSerialPortOption]``>
+ void ``[link asio.reference.serial_port.set_option.overload2 set_option]``(
+ const SettableSerialPortOption & option,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.set_option.overload2 more...]]``
+
+
+[section:overload1 serial_port::set_option (1 of 2 overloads)]
+
+
+Set an option on the serial port.
+
+
+ template<
+ typename ``[link asio.reference.SettableSerialPortOption SettableSerialPortOption]``>
+ void set_option(
+ const SettableSerialPortOption & option);
+
+
+This function is used to set an option on the serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be set on the serial port.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::set_option (2 of 2 overloads)]
+
+
+Set an option on the serial port.
+
+
+ template<
+ typename ``[link asio.reference.SettableSerialPortOption SettableSerialPortOption]``>
+ void set_option(
+ const SettableSerialPortOption & option,
+ asio::error_code & ec);
+
+
+This function is used to set an option on the serial port.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[option][The option value to be set on the serial port.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some serial_port::write_some]
+
+[indexterm2 asio.indexterm.serial_port.write_some..write_some..serial_port]
+Write some data to the serial port.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.serial_port.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.serial_port.write_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.serial_port.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.serial_port.write_some.overload2 more...]]``
+
+
+[section:overload1 serial_port::write_some (1 of 2 overloads)]
+
+
+Write some data to the serial port.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data to the serial port. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the serial port.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ serial_port.write_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 serial_port::write_some (2 of 2 overloads)]
+
+
+Write some data to the serial port.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data to the serial port. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the serial port.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_serial_port serial_port::~serial_port]
+
+[indexterm2 asio.indexterm.serial_port._serial_port..~serial_port..serial_port]
+Destroys the serial port.
+
+
+ ~serial_port();
+
+
+This function destroys the serial port, cancelling any outstanding asynchronous wait operations associated with the serial port as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base serial_port_base]
+
+
+The [link asio.reference.serial_port_base `serial_port_base`] class is used as a base for the basic\_serial\_port class template so that we have a common place to define the serial port options.
+
+
+ class serial_port_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port_base__baud_rate [*baud_rate]]]
+ [Serial port option to permit changing the baud rate. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port_base__character_size [*character_size]]]
+ [Serial port option to permit changing the character size. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port_base__flow_control [*flow_control]]]
+ [Serial port option to permit changing the flow control. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port_base__parity [*parity]]]
+ [Serial port option to permit changing the parity. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.serial_port_base__stop_bits [*stop_bits]]]
+ [Serial port option to permit changing the number of stop bits. ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base._serial_port_base [*~serial_port_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:_serial_port_base serial_port_base::~serial_port_base]
+
+[indexterm2 asio.indexterm.serial_port_base._serial_port_base..~serial_port_base..serial_port_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~serial_port_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base__baud_rate serial_port_base::baud_rate]
+
+
+Serial port option to permit changing the baud rate.
+
+
+ class baud_rate
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base__baud_rate.baud_rate [*baud_rate]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__baud_rate.load [*load]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__baud_rate.store [*store]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__baud_rate.value [*value]]]
+ []
+ ]
+
+]
+
+Implements changing the baud rate for a given serial port.
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:baud_rate serial_port_base::baud_rate::baud_rate]
+
+[indexterm2 asio.indexterm.serial_port_base__baud_rate.baud_rate..baud_rate..serial_port_base::baud_rate]
+
+ baud_rate(
+ unsigned int rate = 0);
+
+
+
+[endsect]
+
+
+
+[section:load serial_port_base::baud_rate::load]
+
+[indexterm2 asio.indexterm.serial_port_base__baud_rate.load..load..serial_port_base::baud_rate]
+
+ void load(
+ const ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:store serial_port_base::baud_rate::store]
+
+[indexterm2 asio.indexterm.serial_port_base__baud_rate.store..store..serial_port_base::baud_rate]
+
+ void store(
+ ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+
+[section:value serial_port_base::baud_rate::value]
+
+[indexterm2 asio.indexterm.serial_port_base__baud_rate.value..value..serial_port_base::baud_rate]
+
+ unsigned int value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base__character_size serial_port_base::character_size]
+
+
+Serial port option to permit changing the character size.
+
+
+ class character_size
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base__character_size.character_size [*character_size]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__character_size.load [*load]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__character_size.store [*store]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__character_size.value [*value]]]
+ []
+ ]
+
+]
+
+Implements changing the character size for a given serial port.
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:character_size serial_port_base::character_size::character_size]
+
+[indexterm2 asio.indexterm.serial_port_base__character_size.character_size..character_size..serial_port_base::character_size]
+
+ character_size(
+ unsigned int t = 8);
+
+
+
+[endsect]
+
+
+
+[section:load serial_port_base::character_size::load]
+
+[indexterm2 asio.indexterm.serial_port_base__character_size.load..load..serial_port_base::character_size]
+
+ void load(
+ const ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:store serial_port_base::character_size::store]
+
+[indexterm2 asio.indexterm.serial_port_base__character_size.store..store..serial_port_base::character_size]
+
+ void store(
+ ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+
+[section:value serial_port_base::character_size::value]
+
+[indexterm2 asio.indexterm.serial_port_base__character_size.value..value..serial_port_base::character_size]
+
+ unsigned int value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base__flow_control serial_port_base::flow_control]
+
+
+Serial port option to permit changing the flow control.
+
+
+ class flow_control
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port_base__flow_control.type [*type]]]
+ []
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base__flow_control.flow_control [*flow_control]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__flow_control.load [*load]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__flow_control.store [*store]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__flow_control.value [*value]]]
+ []
+ ]
+
+]
+
+Implements changing the flow control for a given serial port.
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:flow_control serial_port_base::flow_control::flow_control]
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.flow_control..flow_control..serial_port_base::flow_control]
+
+ flow_control(
+ type t = none);
+
+
+
+[endsect]
+
+
+
+[section:load serial_port_base::flow_control::load]
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.load..load..serial_port_base::flow_control]
+
+ void load(
+ const ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:store serial_port_base::flow_control::store]
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.store..store..serial_port_base::flow_control]
+
+ void store(
+ ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+
+[section:type serial_port_base::flow_control::type]
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.type..type..serial_port_base::flow_control]
+
+ enum type
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.type.none..none..serial_port_base::flow_control]
+[indexterm2 asio.indexterm.serial_port_base__flow_control.type.software..software..serial_port_base::flow_control]
+[indexterm2 asio.indexterm.serial_port_base__flow_control.type.hardware..hardware..serial_port_base::flow_control]
+
+[heading Values]
+[variablelist
+
+ [
+ [none]
+ []
+ ]
+
+ [
+ [software]
+ []
+ ]
+
+ [
+ [hardware]
+ []
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:value serial_port_base::flow_control::value]
+
+[indexterm2 asio.indexterm.serial_port_base__flow_control.value..value..serial_port_base::flow_control]
+
+ type value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base__parity serial_port_base::parity]
+
+
+Serial port option to permit changing the parity.
+
+
+ class parity
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port_base__parity.type [*type]]]
+ []
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base__parity.load [*load]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__parity.parity [*parity]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__parity.store [*store]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__parity.value [*value]]]
+ []
+ ]
+
+]
+
+Implements changing the parity for a given serial port.
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:load serial_port_base::parity::load]
+
+[indexterm2 asio.indexterm.serial_port_base__parity.load..load..serial_port_base::parity]
+
+ void load(
+ const ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:parity serial_port_base::parity::parity]
+
+[indexterm2 asio.indexterm.serial_port_base__parity.parity..parity..serial_port_base::parity]
+
+ parity(
+ type t = none);
+
+
+
+[endsect]
+
+
+
+[section:store serial_port_base::parity::store]
+
+[indexterm2 asio.indexterm.serial_port_base__parity.store..store..serial_port_base::parity]
+
+ void store(
+ ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+
+[section:type serial_port_base::parity::type]
+
+[indexterm2 asio.indexterm.serial_port_base__parity.type..type..serial_port_base::parity]
+
+ enum type
+
+[indexterm2 asio.indexterm.serial_port_base__parity.type.none..none..serial_port_base::parity]
+[indexterm2 asio.indexterm.serial_port_base__parity.type.odd..odd..serial_port_base::parity]
+[indexterm2 asio.indexterm.serial_port_base__parity.type.even..even..serial_port_base::parity]
+
+[heading Values]
+[variablelist
+
+ [
+ [none]
+ []
+ ]
+
+ [
+ [odd]
+ []
+ ]
+
+ [
+ [even]
+ []
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:value serial_port_base::parity::value]
+
+[indexterm2 asio.indexterm.serial_port_base__parity.value..value..serial_port_base::parity]
+
+ type value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:serial_port_base__stop_bits serial_port_base::stop_bits]
+
+
+Serial port option to permit changing the number of stop bits.
+
+
+ class stop_bits
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.serial_port_base__stop_bits.type [*type]]]
+ []
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.serial_port_base__stop_bits.load [*load]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__stop_bits.stop_bits [*stop_bits]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__stop_bits.store [*store]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.serial_port_base__stop_bits.value [*value]]]
+ []
+ ]
+
+]
+
+Implements changing the number of stop bits for a given serial port.
+
+[heading Requirements]
+
+['Header: ][^asio/serial_port_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:load serial_port_base::stop_bits::load]
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.load..load..serial_port_base::stop_bits]
+
+ void load(
+ const ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:stop_bits serial_port_base::stop_bits::stop_bits]
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.stop_bits..stop_bits..serial_port_base::stop_bits]
+
+ stop_bits(
+ type t = one);
+
+
+
+[endsect]
+
+
+
+[section:store serial_port_base::stop_bits::store]
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.store..store..serial_port_base::stop_bits]
+
+ void store(
+ ASIO_OPTION_STORAGE & storage,
+ asio::error_code & ec) const;
+
+
+
+[endsect]
+
+
+
+[section:type serial_port_base::stop_bits::type]
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.type..type..serial_port_base::stop_bits]
+
+ enum type
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.type.one..one..serial_port_base::stop_bits]
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.type.onepointfive..onepointfive..serial_port_base::stop_bits]
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.type.two..two..serial_port_base::stop_bits]
+
+[heading Values]
+[variablelist
+
+ [
+ [one]
+ []
+ ]
+
+ [
+ [onepointfive]
+ []
+ ]
+
+ [
+ [two]
+ []
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:value serial_port_base::stop_bits::value]
+
+[indexterm2 asio.indexterm.serial_port_base__stop_bits.value..value..serial_port_base::stop_bits]
+
+ type value() const;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:service_already_exists service_already_exists]
+
+
+Exception thrown when trying to add a duplicate service to an [link asio.reference.execution_context `execution_context`].
+
+
+ class service_already_exists
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.service_already_exists.service_already_exists [*service_already_exists]]]
+ []
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:service_already_exists service_already_exists::service_already_exists]
+
+[indexterm2 asio.indexterm.service_already_exists.service_already_exists..service_already_exists..service_already_exists]
+
+ service_already_exists();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:signal_set signal_set]
+
+
+Provides signal functionality.
+
+
+ class signal_set
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.signal_set.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.signal_set.add [*add]]]
+ [Add a signal to a signal_set. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.async_wait [*async_wait]]]
+ [Start an asynchronous operation to wait for a signal to be delivered. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.cancel [*cancel]]]
+ [Cancel all operations associated with the signal set. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.clear [*clear]]]
+ [Remove all signals from a signal_set. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.remove [*remove]]]
+ [Remove a signal from a signal_set. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set.signal_set [*signal_set]]]
+ [Construct a signal set without adding any signals.
+
+ Construct a signal set and add one signal.
+
+ Construct a signal set and add two signals.
+
+ Construct a signal set and add three signals. ]
+ ]
+
+ [
+ [[link asio.reference.signal_set._signal_set [*~signal_set]]]
+ [Destroys the signal set. ]
+ ]
+
+]
+
+The [link asio.reference.signal_set `signal_set`] class provides the ability to perform an asynchronous wait for one or more signals to occur.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Example]
+
+Performing an asynchronous wait:
+
+ void handler(
+ const asio::error_code& error,
+ int signal_number)
+ {
+ if (!error)
+ {
+ // A signal occurred.
+ }
+ }
+
+ ...
+
+ // Construct a signal set registered for process termination.
+ asio::signal_set signals(io_context, SIGINT, SIGTERM);
+
+ // Start an asynchronous wait for one of the signals to occur.
+ signals.async_wait(handler);
+
+
+
+
+
+[heading Queueing of signal notifications]
+
+
+
+If a signal is registered with a [link asio.reference.signal_set `signal_set`], and the signal occurs when there are no waiting handlers, then the signal notification is queued. The next async\_wait operation on that [link asio.reference.signal_set `signal_set`] will dequeue the notification. If multiple notifications are queued, subsequent async\_wait operations dequeue them one at a time. Signal notifications are dequeued in order of ascending signal number.
+
+If a signal number is removed from a [link asio.reference.signal_set `signal_set`] (using the `remove` or `erase` member functions) then any queued notifications for that signal are discarded.
+
+
+[heading Multiple registration of signals]
+
+
+
+The same signal number may be registered with different [link asio.reference.signal_set `signal_set`] objects. When the signal occurs, one handler is called for each [link asio.reference.signal_set `signal_set`] object.
+
+Note that multiple registration only works for signals that are registered using Asio. The application must not also register a signal handler using functions such as `signal()` or `sigaction()`.
+
+
+[heading Signal masking on POSIX platforms]
+
+
+
+POSIX allows signals to be blocked using functions such as `sigprocmask()` and `pthread_sigmask()`. For signals to be delivered, programs must ensure that any signals registered using [link asio.reference.signal_set `signal_set`] objects are unblocked in at least one thread.
+
+[heading Requirements]
+
+['Header: ][^asio/signal_set.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:add signal_set::add]
+
+[indexterm2 asio.indexterm.signal_set.add..add..signal_set]
+Add a signal to a [link asio.reference.signal_set `signal_set`].
+
+
+ void ``[link asio.reference.signal_set.add.overload1 add]``(
+ int signal_number);
+ `` [''''&raquo;''' [link asio.reference.signal_set.add.overload1 more...]]``
+
+ void ``[link asio.reference.signal_set.add.overload2 add]``(
+ int signal_number,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.signal_set.add.overload2 more...]]``
+
+
+[section:overload1 signal_set::add (1 of 2 overloads)]
+
+
+Add a signal to a [link asio.reference.signal_set `signal_set`].
+
+
+ void add(
+ int signal_number);
+
+
+This function adds the specified signal to the set. It has no effect if the signal is already in the set.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[signal_number][The signal to be added to the set.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 signal_set::add (2 of 2 overloads)]
+
+
+Add a signal to a [link asio.reference.signal_set `signal_set`].
+
+
+ void add(
+ int signal_number,
+ asio::error_code & ec);
+
+
+This function adds the specified signal to the set. It has no effect if the signal is already in the set.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[signal_number][The signal to be added to the set.]]
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait signal_set::async_wait]
+
+[indexterm2 asio.indexterm.signal_set.async_wait..async_wait..signal_set]
+Start an asynchronous operation to wait for a signal to be delivered.
+
+
+ template<
+ typename ``[link asio.reference.SignalHandler SignalHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ SignalHandler && handler);
+
+
+This function may be used to initiate an asynchronous wait against the signal set. It always returns immediately.
+
+For each call to `async_wait()`, the supplied handler will be called exactly once. The handler will be called when:
+
+
+* One of the registered signals in the signal set occurs; or
+
+
+* The signal set was cancelled, in which case the handler is passed the error code `asio::error::operation_aborted`.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called when the signal occurs. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ int signal_number // Indicates which signal occurred.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:cancel signal_set::cancel]
+
+[indexterm2 asio.indexterm.signal_set.cancel..cancel..signal_set]
+Cancel all operations associated with the signal set.
+
+
+ void ``[link asio.reference.signal_set.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.signal_set.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.signal_set.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.signal_set.cancel.overload2 more...]]``
+
+
+[section:overload1 signal_set::cancel (1 of 2 overloads)]
+
+
+Cancel all operations associated with the signal set.
+
+
+ void cancel();
+
+
+This function forces the completion of any pending asynchronous wait operations against the signal set. The handler for each cancelled operation will be invoked with the `asio::error::operation_aborted` error code.
+
+Cancellation does not alter the set of registered signals.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+If a registered signal occurred before `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+
+[section:overload2 signal_set::cancel (2 of 2 overloads)]
+
+
+Cancel all operations associated with the signal set.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function forces the completion of any pending asynchronous wait operations against the signal set. The handler for each cancelled operation will be invoked with the `asio::error::operation_aborted` error code.
+
+Cancellation does not alter the set of registered signals.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+If a registered signal occurred before `cancel()` is called, then the handlers for asynchronous wait operations will:
+
+
+* have already been invoked; or
+
+
+* 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.
+
+
+[endsect]
+
+
+[endsect]
+
+[section:clear signal_set::clear]
+
+[indexterm2 asio.indexterm.signal_set.clear..clear..signal_set]
+Remove all signals from a [link asio.reference.signal_set `signal_set`].
+
+
+ void ``[link asio.reference.signal_set.clear.overload1 clear]``();
+ `` [''''&raquo;''' [link asio.reference.signal_set.clear.overload1 more...]]``
+
+ void ``[link asio.reference.signal_set.clear.overload2 clear]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.signal_set.clear.overload2 more...]]``
+
+
+[section:overload1 signal_set::clear (1 of 2 overloads)]
+
+
+Remove all signals from a [link asio.reference.signal_set `signal_set`].
+
+
+ void clear();
+
+
+This function removes all signals from the set. It has no effect if the set is already empty.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Removes all queued notifications.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 signal_set::clear (2 of 2 overloads)]
+
+
+Remove all signals from a [link asio.reference.signal_set `signal_set`].
+
+
+ void clear(
+ asio::error_code & ec);
+
+
+This function removes all signals from the set. It has no effect if the set is already empty.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Removes all queued notifications.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type signal_set::executor_type]
+
+[indexterm2 asio.indexterm.signal_set.executor_type..executor_type..signal_set]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/signal_set.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor signal_set::get_executor]
+
+[indexterm2 asio.indexterm.signal_set.get_executor..get_executor..signal_set]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context signal_set::get_io_context]
+
+[indexterm2 asio.indexterm.signal_set.get_io_context..get_io_context..signal_set]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service signal_set::get_io_service]
+
+[indexterm2 asio.indexterm.signal_set.get_io_service..get_io_service..signal_set]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[section:remove signal_set::remove]
+
+[indexterm2 asio.indexterm.signal_set.remove..remove..signal_set]
+Remove a signal from a [link asio.reference.signal_set `signal_set`].
+
+
+ void ``[link asio.reference.signal_set.remove.overload1 remove]``(
+ int signal_number);
+ `` [''''&raquo;''' [link asio.reference.signal_set.remove.overload1 more...]]``
+
+ void ``[link asio.reference.signal_set.remove.overload2 remove]``(
+ int signal_number,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.signal_set.remove.overload2 more...]]``
+
+
+[section:overload1 signal_set::remove (1 of 2 overloads)]
+
+
+Remove a signal from a [link asio.reference.signal_set `signal_set`].
+
+
+ void remove(
+ int signal_number);
+
+
+This function removes the specified signal from the set. It has no effect if the signal is not in the set.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[signal_number][The signal to be removed from the set.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Removes any notifications that have been queued for the specified signal number.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 signal_set::remove (2 of 2 overloads)]
+
+
+Remove a signal from a [link asio.reference.signal_set `signal_set`].
+
+
+ void remove(
+ int signal_number,
+ asio::error_code & ec);
+
+
+This function removes the specified signal from the set. It has no effect if the signal is not in the set.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[signal_number][The signal to be removed from the set.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Removes any notifications that have been queued for the specified signal number.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:signal_set signal_set::signal_set]
+
+[indexterm2 asio.indexterm.signal_set.signal_set..signal_set..signal_set]
+Construct a signal set without adding any signals.
+
+
+ explicit ``[link asio.reference.signal_set.signal_set.overload1 signal_set]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.signal_set.signal_set.overload1 more...]]``
+
+
+Construct a signal set and add one signal.
+
+
+ ``[link asio.reference.signal_set.signal_set.overload2 signal_set]``(
+ asio::io_context & io_context,
+ int signal_number_1);
+ `` [''''&raquo;''' [link asio.reference.signal_set.signal_set.overload2 more...]]``
+
+
+Construct a signal set and add two signals.
+
+
+ ``[link asio.reference.signal_set.signal_set.overload3 signal_set]``(
+ asio::io_context & io_context,
+ int signal_number_1,
+ int signal_number_2);
+ `` [''''&raquo;''' [link asio.reference.signal_set.signal_set.overload3 more...]]``
+
+
+Construct a signal set and add three signals.
+
+
+ ``[link asio.reference.signal_set.signal_set.overload4 signal_set]``(
+ asio::io_context & io_context,
+ int signal_number_1,
+ int signal_number_2,
+ int signal_number_3);
+ `` [''''&raquo;''' [link asio.reference.signal_set.signal_set.overload4 more...]]``
+
+
+[section:overload1 signal_set::signal_set (1 of 4 overloads)]
+
+
+Construct a signal set without adding any signals.
+
+
+ signal_set(
+ asio::io_context & io_context);
+
+
+This constructor creates a signal set without registering for any signals.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the signal set will use to dispatch handlers for any asynchronous operations performed on the set. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 signal_set::signal_set (2 of 4 overloads)]
+
+
+Construct a signal set and add one signal.
+
+
+ signal_set(
+ asio::io_context & io_context,
+ int signal_number_1);
+
+
+This constructor creates a signal set and registers for one signal.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the signal set will use to dispatch handlers for any asynchronous operations performed on the set.]]
+
+[[signal_number_1][The signal number to be added.]]
+
+]
+
+
+[heading Remarks]
+
+This constructor is equivalent to performing:
+
+ asio::signal_set signals(io_context);
+ signals.add(signal_number_1);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 signal_set::signal_set (3 of 4 overloads)]
+
+
+Construct a signal set and add two signals.
+
+
+ signal_set(
+ asio::io_context & io_context,
+ int signal_number_1,
+ int signal_number_2);
+
+
+This constructor creates a signal set and registers for two signals.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the signal set will use to dispatch handlers for any asynchronous operations performed on the set.]]
+
+[[signal_number_1][The first signal number to be added.]]
+
+[[signal_number_2][The second signal number to be added.]]
+
+]
+
+
+[heading Remarks]
+
+This constructor is equivalent to performing:
+
+ asio::signal_set signals(io_context);
+ signals.add(signal_number_1);
+ signals.add(signal_number_2);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 signal_set::signal_set (4 of 4 overloads)]
+
+
+Construct a signal set and add three signals.
+
+
+ signal_set(
+ asio::io_context & io_context,
+ int signal_number_1,
+ int signal_number_2,
+ int signal_number_3);
+
+
+This constructor creates a signal set and registers for three signals.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the signal set will use to dispatch handlers for any asynchronous operations performed on the set.]]
+
+[[signal_number_1][The first signal number to be added.]]
+
+[[signal_number_2][The second signal number to be added.]]
+
+[[signal_number_3][The third signal number to be added.]]
+
+]
+
+
+[heading Remarks]
+
+This constructor is equivalent to performing:
+
+ asio::signal_set signals(io_context);
+ signals.add(signal_number_1);
+ signals.add(signal_number_2);
+ signals.add(signal_number_3);
+
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_signal_set signal_set::~signal_set]
+
+[indexterm2 asio.indexterm.signal_set._signal_set..~signal_set..signal_set]
+Destroys the signal set.
+
+
+ ~signal_set();
+
+
+This function destroys the signal set, cancelling any outstanding asynchronous wait operations associated with the signal set as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:socket_base socket_base]
+
+
+The [link asio.reference.socket_base `socket_base`] class is used as a base for the [link asio.reference.basic_stream_socket `basic_stream_socket`] and [link asio.reference.basic_datagram_socket `basic_datagram_socket`] class templates so that we have a common place to define the shutdown\_type and enum.
+
+
+ class socket_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.socket_base.broadcast [*broadcast]]]
+ [Socket option to permit sending of broadcast messages. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.bytes_readable [*bytes_readable]]]
+ [IO control command to get the amount of data that can be read without blocking. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.debug [*debug]]]
+ [Socket option to enable socket-level debugging. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.do_not_route [*do_not_route]]]
+ [Socket option to prevent routing, use local interfaces only. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.enable_connection_aborted [*enable_connection_aborted]]]
+ [Socket option to report aborted connections on accept. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.keep_alive [*keep_alive]]]
+ [Socket option to send keep-alives. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.linger [*linger]]]
+ [Socket option to specify whether the socket lingers on close if unsent data is present. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.message_flags [*message_flags]]]
+ [Bitmask type for flags that can be passed to send and receive operations. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.receive_buffer_size [*receive_buffer_size]]]
+ [Socket option for the receive buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.receive_low_watermark [*receive_low_watermark]]]
+ [Socket option for the receive low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.reuse_address [*reuse_address]]]
+ [Socket option to allow the socket to be bound to an address that is already in use. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.send_buffer_size [*send_buffer_size]]]
+ [Socket option for the send buffer size of a socket. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.send_low_watermark [*send_low_watermark]]]
+ [Socket option for the send low watermark. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.shutdown_type [*shutdown_type]]]
+ [Different ways a socket may be shutdown. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.socket_base.wait_type [*wait_type]]]
+ [Wait types. ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.socket_base._socket_base [*~socket_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.socket_base.max_connections [*max_connections]]]
+ [(Deprecated: Use max_listen_connections.) The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.socket_base.max_listen_connections [*max_listen_connections]]]
+ [The maximum length of the queue of pending incoming connections. ]
+ ]
+
+ [
+ [[link asio.reference.socket_base.message_do_not_route [*message_do_not_route]]]
+ [Specify that the data should not be subject to routing. ]
+ ]
+
+ [
+ [[link asio.reference.socket_base.message_end_of_record [*message_end_of_record]]]
+ [Specifies that the data marks the end of a record. ]
+ ]
+
+ [
+ [[link asio.reference.socket_base.message_out_of_band [*message_out_of_band]]]
+ [Process out-of-band data. ]
+ ]
+
+ [
+ [[link asio.reference.socket_base.message_peek [*message_peek]]]
+ [Peek at incoming data without removing it from the input queue. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:broadcast socket_base::broadcast]
+
+[indexterm2 asio.indexterm.socket_base.broadcast..broadcast..socket_base]
+Socket option to permit sending of broadcast messages.
+
+
+ typedef implementation_defined broadcast;
+
+
+
+Implements the SOL\_SOCKET/SO\_BROADCAST socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::broadcast option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:bytes_readable socket_base::bytes_readable]
+
+[indexterm2 asio.indexterm.socket_base.bytes_readable..bytes_readable..socket_base]
+IO control command to get the amount of data that can be read without blocking.
+
+
+ typedef implementation_defined bytes_readable;
+
+
+
+Implements the FIONREAD IO control command.
+
+
+[heading Example]
+
+
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::bytes_readable command(true);
+ socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:debug socket_base::debug]
+
+[indexterm2 asio.indexterm.socket_base.debug..debug..socket_base]
+Socket option to enable socket-level debugging.
+
+
+ typedef implementation_defined debug;
+
+
+
+Implements the SOL\_SOCKET/SO\_DEBUG socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::debug option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:do_not_route socket_base::do_not_route]
+
+[indexterm2 asio.indexterm.socket_base.do_not_route..do_not_route..socket_base]
+Socket option to prevent routing, use local interfaces only.
+
+
+ typedef implementation_defined do_not_route;
+
+
+
+Implements the SOL\_SOCKET/SO\_DONTROUTE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::udp::socket socket(io_context);
+ ...
+ asio::socket_base::do_not_route option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:enable_connection_aborted socket_base::enable_connection_aborted]
+
+[indexterm2 asio.indexterm.socket_base.enable_connection_aborted..enable_connection_aborted..socket_base]
+Socket option to report aborted connections on accept.
+
+
+ typedef implementation_defined enable_connection_aborted;
+
+
+
+Implements a custom socket option that determines whether or not an accept operation is permitted to fail with `asio::error::connection_aborted`. By default the option is false.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::enable_connection_aborted option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:keep_alive socket_base::keep_alive]
+
+[indexterm2 asio.indexterm.socket_base.keep_alive..keep_alive..socket_base]
+Socket option to send keep-alives.
+
+
+ typedef implementation_defined keep_alive;
+
+
+
+Implements the SOL\_SOCKET/SO\_KEEPALIVE socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option(true);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::keep_alive option;
+ socket.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:linger socket_base::linger]
+
+[indexterm2 asio.indexterm.socket_base.linger..linger..socket_base]
+Socket option to specify whether the socket lingers on close if unsent data is present.
+
+
+ typedef implementation_defined linger;
+
+
+
+Implements the SOL\_SOCKET/SO\_LINGER socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option(true, 30);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::linger option;
+ socket.get_option(option);
+ bool is_set = option.enabled();
+ unsigned short timeout = option.timeout();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:max_connections socket_base::max_connections]
+
+[indexterm2 asio.indexterm.socket_base.max_connections..max_connections..socket_base]
+(Deprecated: Use max\_listen\_connections.) The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:max_listen_connections socket_base::max_listen_connections]
+
+[indexterm2 asio.indexterm.socket_base.max_listen_connections..max_listen_connections..socket_base]
+The maximum length of the queue of pending incoming connections.
+
+
+ static const int max_listen_connections = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_do_not_route socket_base::message_do_not_route]
+
+[indexterm2 asio.indexterm.socket_base.message_do_not_route..message_do_not_route..socket_base]
+Specify that the data should not be subject to routing.
+
+
+ static const int message_do_not_route = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_end_of_record socket_base::message_end_of_record]
+
+[indexterm2 asio.indexterm.socket_base.message_end_of_record..message_end_of_record..socket_base]
+Specifies that the data marks the end of a record.
+
+
+ static const int message_end_of_record = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_flags socket_base::message_flags]
+
+[indexterm2 asio.indexterm.socket_base.message_flags..message_flags..socket_base]
+Bitmask type for flags that can be passed to send and receive operations.
+
+
+ typedef int message_flags;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:message_out_of_band socket_base::message_out_of_band]
+
+[indexterm2 asio.indexterm.socket_base.message_out_of_band..message_out_of_band..socket_base]
+Process out-of-band data.
+
+
+ static const int message_out_of_band = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:message_peek socket_base::message_peek]
+
+[indexterm2 asio.indexterm.socket_base.message_peek..message_peek..socket_base]
+Peek at incoming data without removing it from the input queue.
+
+
+ static const int message_peek = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:receive_buffer_size socket_base::receive_buffer_size]
+
+[indexterm2 asio.indexterm.socket_base.receive_buffer_size..receive_buffer_size..socket_base]
+Socket option for the receive buffer size of a socket.
+
+
+ typedef implementation_defined receive_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:receive_low_watermark socket_base::receive_low_watermark]
+
+[indexterm2 asio.indexterm.socket_base.receive_low_watermark..receive_low_watermark..socket_base]
+Socket option for the receive low watermark.
+
+
+ typedef implementation_defined receive_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_RCVLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::receive_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:reuse_address socket_base::reuse_address]
+
+[indexterm2 asio.indexterm.socket_base.reuse_address..reuse_address..socket_base]
+Socket option to allow the socket to be bound to an address that is already in use.
+
+
+ typedef implementation_defined reuse_address;
+
+
+
+Implements the SOL\_SOCKET/SO\_REUSEADDR socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option(true);
+ acceptor.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::acceptor acceptor(io_context);
+ ...
+ asio::socket_base::reuse_address option;
+ acceptor.get_option(option);
+ bool is_set = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_buffer_size socket_base::send_buffer_size]
+
+[indexterm2 asio.indexterm.socket_base.send_buffer_size..send_buffer_size..socket_base]
+Socket option for the send buffer size of a socket.
+
+
+ typedef implementation_defined send_buffer_size;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDBUF socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option(8192);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_buffer_size option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:send_low_watermark socket_base::send_low_watermark]
+
+[indexterm2 asio.indexterm.socket_base.send_low_watermark..send_low_watermark..socket_base]
+Socket option for the send low watermark.
+
+
+ typedef implementation_defined send_low_watermark;
+
+
+
+Implements the SOL\_SOCKET/SO\_SNDLOWAT socket option.
+
+
+[heading Examples]
+
+Setting the option:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option(1024);
+ socket.set_option(option);
+
+
+
+
+
+Getting the current option value:
+
+ asio::ip::tcp::socket socket(io_context);
+ ...
+ asio::socket_base::send_low_watermark option;
+ socket.get_option(option);
+ int size = option.value();
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/socket_base.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:shutdown_type socket_base::shutdown_type]
+
+[indexterm2 asio.indexterm.socket_base.shutdown_type..shutdown_type..socket_base]
+Different ways a socket may be shutdown.
+
+
+ enum shutdown_type
+
+[indexterm2 asio.indexterm.socket_base.shutdown_type.shutdown_receive..shutdown_receive..socket_base]
+[indexterm2 asio.indexterm.socket_base.shutdown_type.shutdown_send..shutdown_send..socket_base]
+[indexterm2 asio.indexterm.socket_base.shutdown_type.shutdown_both..shutdown_both..socket_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [shutdown_receive]
+ [Shutdown the receive side of the socket. ]
+ ]
+
+ [
+ [shutdown_send]
+ [Shutdown the send side of the socket. ]
+ ]
+
+ [
+ [shutdown_both]
+ [Shutdown both send and receive on the socket. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:wait_type socket_base::wait_type]
+
+[indexterm2 asio.indexterm.socket_base.wait_type..wait_type..socket_base]
+Wait types.
+
+
+ enum wait_type
+
+[indexterm2 asio.indexterm.socket_base.wait_type.wait_read..wait_read..socket_base]
+[indexterm2 asio.indexterm.socket_base.wait_type.wait_write..wait_write..socket_base]
+[indexterm2 asio.indexterm.socket_base.wait_type.wait_error..wait_error..socket_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [wait_read]
+ [Wait for a socket to become ready to read. ]
+ ]
+
+ [
+ [wait_write]
+ [Wait for a socket to become ready to write. ]
+ ]
+
+ [
+ [wait_error]
+ [Wait for a socket to have error conditions pending. ]
+ ]
+
+]
+
+
+For use with `basic_socket::wait()` and `basic_socket::async_wait()`.
+
+
+[endsect]
+
+
+
+[section:_socket_base socket_base::~socket_base]
+
+[indexterm2 asio.indexterm.socket_base._socket_base..~socket_base..socket_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~socket_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:spawn spawn]
+
+[indexterm1 asio.indexterm.spawn..spawn]
+Start a new stackful coroutine.
+
+
+ template<
+ typename Function>
+ void ``[link asio.reference.spawn.overload1 spawn]``(
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+ `` [''''&raquo;''' [link asio.reference.spawn.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``,
+ typename Function>
+ void ``[link asio.reference.spawn.overload2 spawn]``(
+ Handler && handler,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if<!is_executor< typename decay< Handler >::type >::value &&!is_convertible< Handler &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.spawn.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``,
+ typename Function>
+ void ``[link asio.reference.spawn.overload3 spawn]``(
+ basic_yield_context< Handler > ctx,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+ `` [''''&raquo;''' [link asio.reference.spawn.overload3 more...]]``
+
+ template<
+ typename Function,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ void ``[link asio.reference.spawn.overload4 spawn]``(
+ const Executor & ex,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.spawn.overload4 more...]]``
+
+ template<
+ typename Function,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ void ``[link asio.reference.spawn.overload5 spawn]``(
+ const strand< Executor > & ex,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+ `` [''''&raquo;''' [link asio.reference.spawn.overload5 more...]]``
+
+ template<
+ typename Function>
+ void ``[link asio.reference.spawn.overload6 spawn]``(
+ const asio::io_context::strand & s,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+ `` [''''&raquo;''' [link asio.reference.spawn.overload6 more...]]``
+
+ template<
+ typename Function,
+ typename ExecutionContext>
+ void ``[link asio.reference.spawn.overload7 spawn]``(
+ ExecutionContext & ctx,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.spawn.overload7 more...]]``
+
+The `spawn()` function is a high-level wrapper over the Boost.Coroutine library. This function enables programs to implement asynchronous logic in a synchronous manner, as illustrated by the following example:
+
+
+
+ asio::spawn(my_strand, do_echo);
+
+ // ...
+
+ void do_echo(asio::yield_context yield)
+ {
+ try
+ {
+ char data[128];
+ for (;;)
+ {
+ std::size_t length =
+ my_socket.async_read_some(
+ asio::buffer(data), yield);
+
+ asio::async_write(my_socket,
+ asio::buffer(data, length), yield);
+ }
+ }
+ catch (std::exception& e)
+ {
+ // ...
+ }
+ }
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/spawn.hpp]
+
+['Convenience header: ]None
+
+
+[section:overload1 spawn (1 of 7 overloads)]
+
+
+Start a new stackful coroutine, calling the specified handler when it completes.
+
+
+ template<
+ typename Function>
+ void spawn(
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(basic_yield_context<Handler> yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 spawn (2 of 7 overloads)]
+
+
+Start a new stackful coroutine, calling the specified handler when it completes.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``,
+ typename Function>
+ void spawn(
+ Handler && handler,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if<!is_executor< typename decay< Handler >::type >::value &&!is_convertible< Handler &, execution_context & >::value >::type * = 0);
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][A handler to be called when the coroutine exits. More importantly, the handler provides an execution context (via the the handler invocation hook) for the coroutine. The handler must have the signature:
+``
+ void handler();
+``
+]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(basic_yield_context<Handler> yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 spawn (3 of 7 overloads)]
+
+
+Start a new stackful coroutine, inheriting the execution context of another.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``,
+ typename Function>
+ void spawn(
+ basic_yield_context< Handler > ctx,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ctx][Identifies the current coroutine as a parent of the new coroutine. This specifies that the new coroutine should inherit the execution context of the parent. For example, if the parent coroutine is executing in a particular strand, then the new coroutine will execute in the same strand.]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(basic_yield_context<Handler> yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 spawn (4 of 7 overloads)]
+
+
+Start a new stackful coroutine that executes on a given executor.
+
+
+ template<
+ typename Function,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ void spawn(
+ const Executor & ex,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if< is_executor< Executor >::value >::type * = 0);
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ex][Identifies the executor that will run the coroutine. The new coroutine is implicitly given its own strand within this executor.]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(yield_context yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 spawn (5 of 7 overloads)]
+
+
+Start a new stackful coroutine that executes on a given strand.
+
+
+ template<
+ typename Function,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ void spawn(
+ const strand< Executor > & ex,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ex][Identifies the strand that will run the coroutine.]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(yield_context yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 spawn (6 of 7 overloads)]
+
+
+Start a new stackful coroutine that executes in the context of a strand.
+
+
+ template<
+ typename Function>
+ void spawn(
+ const asio::io_context::strand & s,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes());
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][Identifies a strand. By starting multiple coroutines on the same strand, the implementation ensures that none of those coroutines can execute simultaneously.]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(yield_context yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 spawn (7 of 7 overloads)]
+
+
+Start a new stackful coroutine that executes on a given execution context.
+
+
+ template<
+ typename Function,
+ typename ExecutionContext>
+ void spawn(
+ ExecutionContext & ctx,
+ Function && function,
+ const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
+ typename enable_if< is_convertible< ExecutionContext &, execution_context & >::value >::type * = 0);
+
+
+This function is used to launch a new coroutine.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ctx][Identifies the execution context that will run the coroutine. The new coroutine is implicitly given its own strand within this execution context.]]
+
+[[function][The coroutine function. The function must have the signature:
+``
+ void function(yield_context yield);
+``
+]]
+
+[[attributes][Boost.Coroutine attributes used to customise the coroutine. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:ssl__context ssl::context]
+
+
+
+ class context :
+ public ssl::context_base,
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__context.file_format [*file_format]]]
+ [File format types. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context.method [*method]]]
+ [Different methods supported by a context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context.native_handle_type [*native_handle_type]]]
+ [The native handle type of the SSL context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context.options [*options]]]
+ [Bitmask type for SSL options. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context.password_purpose [*password_purpose]]]
+ [Purpose of PEM password. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__context.add_certificate_authority [*add_certificate_authority]]]
+ [Add certification authority for performing verification. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.add_verify_path [*add_verify_path]]]
+ [Add a directory containing certificate authority files to be used for performing verification. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.clear_options [*clear_options]]]
+ [Clear options on the context. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.context [*context]]]
+ [Constructor.
+
+ Move-construct a context from another. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.load_verify_file [*load_verify_file]]]
+ [Load a certification authority file for performing verification. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.native_handle [*native_handle]]]
+ [Get the underlying implementation in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.operator_eq_ [*operator=]]]
+ [Move-assign a context from another. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_default_verify_paths [*set_default_verify_paths]]]
+ [Configures the context to use the default directories for finding certification authority certificates. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_options [*set_options]]]
+ [Set options on the context. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_password_callback [*set_password_callback]]]
+ [Set the password callback. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_verify_callback [*set_verify_callback]]]
+ [Set the callback used to verify peer certificates. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_verify_depth [*set_verify_depth]]]
+ [Set the peer verification depth. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.set_verify_mode [*set_verify_mode]]]
+ [Set the peer verification mode. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_certificate [*use_certificate]]]
+ [Use a certificate from a memory buffer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_certificate_chain [*use_certificate_chain]]]
+ [Use a certificate chain from a memory buffer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_certificate_chain_file [*use_certificate_chain_file]]]
+ [Use a certificate chain from a file. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_certificate_file [*use_certificate_file]]]
+ [Use a certificate from a file. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_private_key [*use_private_key]]]
+ [Use a private key from a memory buffer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_private_key_file [*use_private_key_file]]]
+ [Use a private key from a file. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_rsa_private_key [*use_rsa_private_key]]]
+ [Use an RSA private key from a memory buffer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_rsa_private_key_file [*use_rsa_private_key_file]]]
+ [Use an RSA private key from a file. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_tmp_dh [*use_tmp_dh]]]
+ [Use the specified memory buffer to obtain the temporary Diffie-Hellman parameters. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.use_tmp_dh_file [*use_tmp_dh_file]]]
+ [Use the specified file to obtain the temporary Diffie-Hellman parameters. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context._context [*~context]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__context.default_workarounds [*default_workarounds]]]
+ [Implement various bug workarounds. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_compression [*no_compression]]]
+ [Disable compression. Compression is disabled by default. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_sslv2 [*no_sslv2]]]
+ [Disable SSL v2. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_sslv3 [*no_sslv3]]]
+ [Disable SSL v3. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_tlsv1 [*no_tlsv1]]]
+ [Disable TLS v1. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_tlsv1_1 [*no_tlsv1_1]]]
+ [Disable TLS v1.1. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.no_tlsv1_2 [*no_tlsv1_2]]]
+ [Disable TLS v1.2. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context.single_dh_use [*single_dh_use]]]
+ [Always create a new key when using tmp_dh parameters. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/context.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+[section:add_certificate_authority ssl::context::add_certificate_authority]
+
+[indexterm2 asio.indexterm.ssl__context.add_certificate_authority..add_certificate_authority..ssl::context]
+Add certification authority for performing verification.
+
+
+ void ``[link asio.reference.ssl__context.add_certificate_authority.overload1 add_certificate_authority]``(
+ const const_buffer & ca);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.add_certificate_authority.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.add_certificate_authority.overload2 add_certificate_authority]``(
+ const const_buffer & ca,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.add_certificate_authority.overload2 more...]]``
+
+
+[section:overload1 ssl::context::add_certificate_authority (1 of 2 overloads)]
+
+
+Add certification authority for performing verification.
+
+
+ void add_certificate_authority(
+ const const_buffer & ca);
+
+
+This function is used to add one trusted certification authority from a memory buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ca][The buffer containing the certification authority certificate. The certificate must use the PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_get_cert_store` and `X509_STORE_add_cert`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::add_certificate_authority (2 of 2 overloads)]
+
+
+Add certification authority for performing verification.
+
+
+ void add_certificate_authority(
+ const const_buffer & ca,
+ asio::error_code & ec);
+
+
+This function is used to add one trusted certification authority from a memory buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ca][The buffer containing the certification authority certificate. The certificate must use the PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_get_cert_store` and `X509_STORE_add_cert`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:add_verify_path ssl::context::add_verify_path]
+
+[indexterm2 asio.indexterm.ssl__context.add_verify_path..add_verify_path..ssl::context]
+Add a directory containing certificate authority files to be used for performing verification.
+
+
+ void ``[link asio.reference.ssl__context.add_verify_path.overload1 add_verify_path]``(
+ const std::string & path);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.add_verify_path.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.add_verify_path.overload2 add_verify_path]``(
+ const std::string & path,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.add_verify_path.overload2 more...]]``
+
+
+[section:overload1 ssl::context::add_verify_path (1 of 2 overloads)]
+
+
+Add a directory containing certificate authority files to be used for performing verification.
+
+
+ void add_verify_path(
+ const std::string & path);
+
+
+This function is used to specify the name of a directory containing certification authority certificates. Each file in the directory must contain a single certificate. The files must be named using the subject name's hash and an extension of ".0".
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[path][The name of a directory containing the certificates.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_load_verify_locations`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::add_verify_path (2 of 2 overloads)]
+
+
+Add a directory containing certificate authority files to be used for performing verification.
+
+
+ void add_verify_path(
+ const std::string & path,
+ asio::error_code & ec);
+
+
+This function is used to specify the name of a directory containing certification authority certificates. Each file in the directory must contain a single certificate. The files must be named using the subject name's hash and an extension of ".0".
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[path][The name of a directory containing the certificates.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_load_verify_locations`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:clear_options ssl::context::clear_options]
+
+[indexterm2 asio.indexterm.ssl__context.clear_options..clear_options..ssl::context]
+Clear options on the context.
+
+
+ void ``[link asio.reference.ssl__context.clear_options.overload1 clear_options]``(
+ options o);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.clear_options.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.clear_options.overload2 clear_options]``(
+ options o,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.clear_options.overload2 more...]]``
+
+
+[section:overload1 ssl::context::clear_options (1 of 2 overloads)]
+
+
+Clear options on the context.
+
+
+ void clear_options(
+ options o);
+
+
+This function may be used to configure the SSL options used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[o][A bitmask of options. The available option values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class. The specified options, if currently enabled on the context, are cleared.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_clear_options`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::clear_options (2 of 2 overloads)]
+
+
+Clear options on the context.
+
+
+ void clear_options(
+ options o,
+ asio::error_code & ec);
+
+
+This function may be used to configure the SSL options used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[o][A bitmask of options. The available option values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class. The specified options, if currently enabled on the context, are cleared.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_clear_options`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:context ssl::context::context]
+
+[indexterm2 asio.indexterm.ssl__context.context..context..ssl::context]
+Constructor.
+
+
+ explicit ``[link asio.reference.ssl__context.context.overload1 context]``(
+ method m);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.context.overload1 more...]]``
+
+
+Move-construct a context from another.
+
+
+ ``[link asio.reference.ssl__context.context.overload2 context]``(
+ context && other);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.context.overload2 more...]]``
+
+
+[section:overload1 ssl::context::context (1 of 2 overloads)]
+
+
+Constructor.
+
+
+ context(
+ method m);
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::context (2 of 2 overloads)]
+
+
+Move-construct a context from another.
+
+
+ context(
+ context && other);
+
+
+This constructor moves an SSL context from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other context object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the following operations only are valid for the moved-from object:
+* Destruction.
+
+* As a target for move-assignment.
+
+
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:default_workarounds ssl::context::default_workarounds]
+
+[indexterm2 asio.indexterm.ssl__context.default_workarounds..default_workarounds..ssl::context]
+Implement various bug workarounds.
+
+
+ static const long default_workarounds = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:file_format ssl::context::file_format]
+
+[indexterm2 asio.indexterm.ssl__context.file_format..file_format..ssl::context]
+File format types.
+
+
+ enum file_format
+
+[indexterm2 asio.indexterm.ssl__context.file_format.asn1..asn1..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.file_format.pem..pem..ssl::context]
+
+[heading Values]
+[variablelist
+
+ [
+ [asn1]
+ [ASN.1 file. ]
+ ]
+
+ [
+ [pem]
+ [PEM file. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:load_verify_file ssl::context::load_verify_file]
+
+[indexterm2 asio.indexterm.ssl__context.load_verify_file..load_verify_file..ssl::context]
+Load a certification authority file for performing verification.
+
+
+ void ``[link asio.reference.ssl__context.load_verify_file.overload1 load_verify_file]``(
+ const std::string & filename);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.load_verify_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.load_verify_file.overload2 load_verify_file]``(
+ const std::string & filename,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.load_verify_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::load_verify_file (1 of 2 overloads)]
+
+
+Load a certification authority file for performing verification.
+
+
+ void load_verify_file(
+ const std::string & filename);
+
+
+This function is used to load one or more trusted certification authorities from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of a file containing certification authority certificates in PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_load_verify_locations`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::load_verify_file (2 of 2 overloads)]
+
+
+Load a certification authority file for performing verification.
+
+
+ void load_verify_file(
+ const std::string & filename,
+ asio::error_code & ec);
+
+
+This function is used to load the certificates for one or more trusted certification authorities from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of a file containing certification authority certificates in PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_load_verify_locations`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:method ssl::context::method]
+
+[indexterm2 asio.indexterm.ssl__context.method..method..ssl::context]
+Different methods supported by a context.
+
+
+ enum method
+
+[indexterm2 asio.indexterm.ssl__context.method.sslv2..sslv2..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv2_client..sslv2_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv2_server..sslv2_server..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv3..sslv3..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv3_client..sslv3_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv3_server..sslv3_server..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv1..tlsv1..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv1_client..tlsv1_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv1_server..tlsv1_server..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv23..sslv23..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv23_client..sslv23_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.sslv23_server..sslv23_server..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv11..tlsv11..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv11_client..tlsv11_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv11_server..tlsv11_server..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv12..tlsv12..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv12_client..tlsv12_client..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.method.tlsv12_server..tlsv12_server..ssl::context]
+
+[heading Values]
+[variablelist
+
+ [
+ [sslv2]
+ [Generic SSL version 2. ]
+ ]
+
+ [
+ [sslv2_client]
+ [SSL version 2 client. ]
+ ]
+
+ [
+ [sslv2_server]
+ [SSL version 2 server. ]
+ ]
+
+ [
+ [sslv3]
+ [Generic SSL version 3. ]
+ ]
+
+ [
+ [sslv3_client]
+ [SSL version 3 client. ]
+ ]
+
+ [
+ [sslv3_server]
+ [SSL version 3 server. ]
+ ]
+
+ [
+ [tlsv1]
+ [Generic TLS version 1. ]
+ ]
+
+ [
+ [tlsv1_client]
+ [TLS version 1 client. ]
+ ]
+
+ [
+ [tlsv1_server]
+ [TLS version 1 server. ]
+ ]
+
+ [
+ [sslv23]
+ [Generic SSL/TLS. ]
+ ]
+
+ [
+ [sslv23_client]
+ [SSL/TLS client. ]
+ ]
+
+ [
+ [sslv23_server]
+ [SSL/TLS server. ]
+ ]
+
+ [
+ [tlsv11]
+ [Generic TLS version 1.1. ]
+ ]
+
+ [
+ [tlsv11_client]
+ [TLS version 1.1 client. ]
+ ]
+
+ [
+ [tlsv11_server]
+ [TLS version 1.1 server. ]
+ ]
+
+ [
+ [tlsv12]
+ [Generic TLS version 1.2. ]
+ ]
+
+ [
+ [tlsv12_client]
+ [TLS version 1.2 client. ]
+ ]
+
+ [
+ [tlsv12_server]
+ [TLS version 1.2 server. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:native_handle ssl::context::native_handle]
+
+[indexterm2 asio.indexterm.ssl__context.native_handle..native_handle..ssl::context]
+Get the underlying implementation in the native type.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying implementation of the context. This is intended to allow access to context functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type ssl::context::native_handle_type]
+
+[indexterm2 asio.indexterm.ssl__context.native_handle_type..native_handle_type..ssl::context]
+The native handle type of the SSL context.
+
+
+ typedef SSL_CTX * native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/context.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:no_compression ssl::context::no_compression]
+
+[indexterm2 asio.indexterm.ssl__context.no_compression..no_compression..ssl::context]
+Disable compression. Compression is disabled by default.
+
+
+ static const long no_compression = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_sslv2 ssl::context::no_sslv2]
+
+[indexterm2 asio.indexterm.ssl__context.no_sslv2..no_sslv2..ssl::context]
+Disable SSL v2.
+
+
+ static const long no_sslv2 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_sslv3 ssl::context::no_sslv3]
+
+[indexterm2 asio.indexterm.ssl__context.no_sslv3..no_sslv3..ssl::context]
+Disable SSL v3.
+
+
+ static const long no_sslv3 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1 ssl::context::no_tlsv1]
+
+[indexterm2 asio.indexterm.ssl__context.no_tlsv1..no_tlsv1..ssl::context]
+Disable TLS v1.
+
+
+ static const long no_tlsv1 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1_1 ssl::context::no_tlsv1_1]
+
+[indexterm2 asio.indexterm.ssl__context.no_tlsv1_1..no_tlsv1_1..ssl::context]
+Disable TLS v1.1.
+
+
+ static const long no_tlsv1_1 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1_2 ssl::context::no_tlsv1_2]
+
+[indexterm2 asio.indexterm.ssl__context.no_tlsv1_2..no_tlsv1_2..ssl::context]
+Disable TLS v1.2.
+
+
+ static const long no_tlsv1_2 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ ssl::context::operator=]
+
+[indexterm2 asio.indexterm.ssl__context.operator_eq_..operator=..ssl::context]
+Move-assign a context from another.
+
+
+ context & operator=(
+ context && other);
+
+
+This assignment operator moves an SSL context from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other context object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the following operations only are valid for the moved-from object:
+* Destruction.
+
+* As a target for move-assignment.
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:options ssl::context::options]
+
+[indexterm2 asio.indexterm.ssl__context.options..options..ssl::context]
+Bitmask type for SSL options.
+
+
+ typedef long options;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/context.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:password_purpose ssl::context::password_purpose]
+
+[indexterm2 asio.indexterm.ssl__context.password_purpose..password_purpose..ssl::context]
+Purpose of PEM password.
+
+
+ enum password_purpose
+
+[indexterm2 asio.indexterm.ssl__context.password_purpose.for_reading..for_reading..ssl::context]
+[indexterm2 asio.indexterm.ssl__context.password_purpose.for_writing..for_writing..ssl::context]
+
+[heading Values]
+[variablelist
+
+ [
+ [for_reading]
+ [The password is needed for reading/decryption. ]
+ ]
+
+ [
+ [for_writing]
+ [The password is needed for writing/encryption. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:set_default_verify_paths ssl::context::set_default_verify_paths]
+
+[indexterm2 asio.indexterm.ssl__context.set_default_verify_paths..set_default_verify_paths..ssl::context]
+Configures the context to use the default directories for finding certification authority certificates.
+
+
+ void ``[link asio.reference.ssl__context.set_default_verify_paths.overload1 set_default_verify_paths]``();
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_default_verify_paths.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.set_default_verify_paths.overload2 set_default_verify_paths]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_default_verify_paths.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_default_verify_paths (1 of 2 overloads)]
+
+
+Configures the context to use the default directories for finding certification authority certificates.
+
+
+ void set_default_verify_paths();
+
+
+This function specifies that the context should use the default, system-dependent directories for locating certification authority certificates.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_default_verify_paths`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_default_verify_paths (2 of 2 overloads)]
+
+
+Configures the context to use the default directories for finding certification authority certificates.
+
+
+ void set_default_verify_paths(
+ asio::error_code & ec);
+
+
+This function specifies that the context should use the default, system-dependent directories for locating certification authority certificates.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_default_verify_paths`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_options ssl::context::set_options]
+
+[indexterm2 asio.indexterm.ssl__context.set_options..set_options..ssl::context]
+Set options on the context.
+
+
+ void ``[link asio.reference.ssl__context.set_options.overload1 set_options]``(
+ options o);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_options.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.set_options.overload2 set_options]``(
+ options o,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_options.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_options (1 of 2 overloads)]
+
+
+Set options on the context.
+
+
+ void set_options(
+ options o);
+
+
+This function may be used to configure the SSL options used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[o][A bitmask of options. The available option values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class. The options are bitwise-ored with any existing value for the options.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_options`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_options (2 of 2 overloads)]
+
+
+Set options on the context.
+
+
+ void set_options(
+ options o,
+ asio::error_code & ec);
+
+
+This function may be used to configure the SSL options used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[o][A bitmask of options. The available option values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class. The options are bitwise-ored with any existing value for the options.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_options`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_password_callback ssl::context::set_password_callback]
+
+[indexterm2 asio.indexterm.ssl__context.set_password_callback..set_password_callback..ssl::context]
+Set the password callback.
+
+
+ template<
+ typename PasswordCallback>
+ void ``[link asio.reference.ssl__context.set_password_callback.overload1 set_password_callback]``(
+ PasswordCallback callback);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_password_callback.overload1 more...]]``
+
+ template<
+ typename PasswordCallback>
+ void ``[link asio.reference.ssl__context.set_password_callback.overload2 set_password_callback]``(
+ PasswordCallback callback,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_password_callback.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_password_callback (1 of 2 overloads)]
+
+
+Set the password callback.
+
+
+ template<
+ typename PasswordCallback>
+ void set_password_callback(
+ PasswordCallback callback);
+
+
+This function is used to specify a callback function to obtain password information about an encrypted key in PEM format.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for obtaining the password. The function signature of the handler must be:
+``
+ std::string password_callback(
+ std::size_t max_length, // The maximum size for a password.
+ password_purpose purpose // Whether password is for reading or writing.
+ );
+``
+The return value of the callback is a string containing the password.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_default_passwd_cb`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_password_callback (2 of 2 overloads)]
+
+
+Set the password callback.
+
+
+ template<
+ typename PasswordCallback>
+ void set_password_callback(
+ PasswordCallback callback,
+ asio::error_code & ec);
+
+
+This function is used to specify a callback function to obtain password information about an encrypted key in PEM format.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for obtaining the password. The function signature of the handler must be:
+``
+ std::string password_callback(
+ std::size_t max_length, // The maximum size for a password.
+ password_purpose purpose // Whether password is for reading or writing.
+ );
+``
+The return value of the callback is a string containing the password.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_default_passwd_cb`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_callback ssl::context::set_verify_callback]
+
+[indexterm2 asio.indexterm.ssl__context.set_verify_callback..set_verify_callback..ssl::context]
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void ``[link asio.reference.ssl__context.set_verify_callback.overload1 set_verify_callback]``(
+ VerifyCallback callback);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_callback.overload1 more...]]``
+
+ template<
+ typename VerifyCallback>
+ void ``[link asio.reference.ssl__context.set_verify_callback.overload2 set_verify_callback]``(
+ VerifyCallback callback,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_callback.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_verify_callback (1 of 2 overloads)]
+
+
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void set_verify_callback(
+ VerifyCallback callback);
+
+
+This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
+``
+ bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ verify_context& ctx // The peer certificate and other context.
+ );
+``
+The return value of the callback is true if the certificate has passed verification, false otherwise.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_verify_callback (2 of 2 overloads)]
+
+
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void set_verify_callback(
+ VerifyCallback callback,
+ asio::error_code & ec);
+
+
+This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
+``
+ bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ verify_context& ctx // The peer certificate and other context.
+ );
+``
+The return value of the callback is true if the certificate has passed verification, false otherwise.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_depth ssl::context::set_verify_depth]
+
+[indexterm2 asio.indexterm.ssl__context.set_verify_depth..set_verify_depth..ssl::context]
+Set the peer verification depth.
+
+
+ void ``[link asio.reference.ssl__context.set_verify_depth.overload1 set_verify_depth]``(
+ int depth);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_depth.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.set_verify_depth.overload2 set_verify_depth]``(
+ int depth,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_depth.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_verify_depth (1 of 2 overloads)]
+
+
+Set the peer verification depth.
+
+
+ void set_verify_depth(
+ int depth);
+
+
+This function may be used to configure the maximum verification depth allowed by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[depth][Maximum depth for the certificate chain verification that shall be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify_depth`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_verify_depth (2 of 2 overloads)]
+
+
+Set the peer verification depth.
+
+
+ void set_verify_depth(
+ int depth,
+ asio::error_code & ec);
+
+
+This function may be used to configure the maximum verification depth allowed by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[depth][Maximum depth for the certificate chain verification that shall be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify_depth`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_mode ssl::context::set_verify_mode]
+
+[indexterm2 asio.indexterm.ssl__context.set_verify_mode..set_verify_mode..ssl::context]
+Set the peer verification mode.
+
+
+ void ``[link asio.reference.ssl__context.set_verify_mode.overload1 set_verify_mode]``(
+ verify_mode v);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_mode.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.set_verify_mode.overload2 set_verify_mode]``(
+ verify_mode v,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_mode.overload2 more...]]``
+
+
+[section:overload1 ssl::context::set_verify_mode (1 of 2 overloads)]
+
+
+Set the peer verification mode.
+
+
+ void set_verify_mode(
+ verify_mode v);
+
+
+This function may be used to configure the peer verification mode used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::set_verify_mode (2 of 2 overloads)]
+
+
+Set the peer verification mode.
+
+
+ void set_verify_mode(
+ verify_mode v,
+ asio::error_code & ec);
+
+
+This function may be used to configure the peer verification mode used by the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_verify`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:single_dh_use ssl::context::single_dh_use]
+
+[indexterm2 asio.indexterm.ssl__context.single_dh_use..single_dh_use..ssl::context]
+Always create a new key when using tmp\_dh parameters.
+
+
+ static const long single_dh_use = implementation_defined;
+
+
+
+[endsect]
+
+
+[section:use_certificate ssl::context::use_certificate]
+
+[indexterm2 asio.indexterm.ssl__context.use_certificate..use_certificate..ssl::context]
+Use a certificate from a memory buffer.
+
+
+ void ``[link asio.reference.ssl__context.use_certificate.overload1 use_certificate]``(
+ const const_buffer & certificate,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_certificate.overload2 use_certificate]``(
+ const const_buffer & certificate,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_certificate (1 of 2 overloads)]
+
+
+Use a certificate from a memory buffer.
+
+
+ void use_certificate(
+ const const_buffer & certificate,
+ file_format format);
+
+
+This function is used to load a certificate into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[certificate][The buffer containing the certificate.]]
+
+[[format][The certificate format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate` or SSL\_CTX\_use\_certificate\_ASN1.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_certificate (2 of 2 overloads)]
+
+
+Use a certificate from a memory buffer.
+
+
+ void use_certificate(
+ const const_buffer & certificate,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load a certificate into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[certificate][The buffer containing the certificate.]]
+
+[[format][The certificate format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate` or SSL\_CTX\_use\_certificate\_ASN1.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_certificate_chain ssl::context::use_certificate_chain]
+
+[indexterm2 asio.indexterm.ssl__context.use_certificate_chain..use_certificate_chain..ssl::context]
+Use a certificate chain from a memory buffer.
+
+
+ void ``[link asio.reference.ssl__context.use_certificate_chain.overload1 use_certificate_chain]``(
+ const const_buffer & chain);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_chain.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_certificate_chain.overload2 use_certificate_chain]``(
+ const const_buffer & chain,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_chain.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_certificate_chain (1 of 2 overloads)]
+
+
+Use a certificate chain from a memory buffer.
+
+
+ void use_certificate_chain(
+ const const_buffer & chain);
+
+
+This function is used to load a certificate chain into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[chain][The buffer containing the certificate chain. The certificate chain must use the PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate` and SSL\_CTX\_add\_extra\_chain\_cert.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_certificate_chain (2 of 2 overloads)]
+
+
+Use a certificate chain from a memory buffer.
+
+
+ void use_certificate_chain(
+ const const_buffer & chain,
+ asio::error_code & ec);
+
+
+This function is used to load a certificate chain into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[chain][The buffer containing the certificate chain. The certificate chain must use the PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate` and SSL\_CTX\_add\_extra\_chain\_cert.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_certificate_chain_file ssl::context::use_certificate_chain_file]
+
+[indexterm2 asio.indexterm.ssl__context.use_certificate_chain_file..use_certificate_chain_file..ssl::context]
+Use a certificate chain from a file.
+
+
+ void ``[link asio.reference.ssl__context.use_certificate_chain_file.overload1 use_certificate_chain_file]``(
+ const std::string & filename);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_chain_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_certificate_chain_file.overload2 use_certificate_chain_file]``(
+ const std::string & filename,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_chain_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_certificate_chain_file (1 of 2 overloads)]
+
+
+Use a certificate chain from a file.
+
+
+ void use_certificate_chain_file(
+ const std::string & filename);
+
+
+This function is used to load a certificate chain into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the certificate. The file must use the PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate_chain_file`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_certificate_chain_file (2 of 2 overloads)]
+
+
+Use a certificate chain from a file.
+
+
+ void use_certificate_chain_file(
+ const std::string & filename,
+ asio::error_code & ec);
+
+
+This function is used to load a certificate chain into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the certificate. The file must use the PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate_chain_file`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_certificate_file ssl::context::use_certificate_file]
+
+[indexterm2 asio.indexterm.ssl__context.use_certificate_file..use_certificate_file..ssl::context]
+Use a certificate from a file.
+
+
+ void ``[link asio.reference.ssl__context.use_certificate_file.overload1 use_certificate_file]``(
+ const std::string & filename,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_certificate_file.overload2 use_certificate_file]``(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_certificate_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_certificate_file (1 of 2 overloads)]
+
+
+Use a certificate from a file.
+
+
+ void use_certificate_file(
+ const std::string & filename,
+ file_format format);
+
+
+This function is used to load a certificate into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the certificate.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate_file`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_certificate_file (2 of 2 overloads)]
+
+
+Use a certificate from a file.
+
+
+ void use_certificate_file(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load a certificate into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the certificate.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_certificate_file`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_private_key ssl::context::use_private_key]
+
+[indexterm2 asio.indexterm.ssl__context.use_private_key..use_private_key..ssl::context]
+Use a private key from a memory buffer.
+
+
+ void ``[link asio.reference.ssl__context.use_private_key.overload1 use_private_key]``(
+ const const_buffer & private_key,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_private_key.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_private_key.overload2 use_private_key]``(
+ const const_buffer & private_key,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_private_key.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_private_key (1 of 2 overloads)]
+
+
+Use a private key from a memory buffer.
+
+
+ void use_private_key(
+ const const_buffer & private_key,
+ file_format format);
+
+
+This function is used to load a private key into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[private_key][The buffer containing the private key.]]
+
+[[format][The private key format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_PrivateKey` or SSL\_CTX\_use\_PrivateKey\_ASN1.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_private_key (2 of 2 overloads)]
+
+
+Use a private key from a memory buffer.
+
+
+ void use_private_key(
+ const const_buffer & private_key,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load a private key into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[private_key][The buffer containing the private key.]]
+
+[[format][The private key format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_PrivateKey` or SSL\_CTX\_use\_PrivateKey\_ASN1.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_private_key_file ssl::context::use_private_key_file]
+
+[indexterm2 asio.indexterm.ssl__context.use_private_key_file..use_private_key_file..ssl::context]
+Use a private key from a file.
+
+
+ void ``[link asio.reference.ssl__context.use_private_key_file.overload1 use_private_key_file]``(
+ const std::string & filename,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_private_key_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_private_key_file.overload2 use_private_key_file]``(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_private_key_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_private_key_file (1 of 2 overloads)]
+
+
+Use a private key from a file.
+
+
+ void use_private_key_file(
+ const std::string & filename,
+ file_format format);
+
+
+This function is used to load a private key into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the private key.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_PrivateKey_file`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_private_key_file (2 of 2 overloads)]
+
+
+Use a private key from a file.
+
+
+ void use_private_key_file(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load a private key into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the private key.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_PrivateKey_file`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_rsa_private_key ssl::context::use_rsa_private_key]
+
+[indexterm2 asio.indexterm.ssl__context.use_rsa_private_key..use_rsa_private_key..ssl::context]
+Use an RSA private key from a memory buffer.
+
+
+ void ``[link asio.reference.ssl__context.use_rsa_private_key.overload1 use_rsa_private_key]``(
+ const const_buffer & private_key,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_rsa_private_key.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_rsa_private_key.overload2 use_rsa_private_key]``(
+ const const_buffer & private_key,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_rsa_private_key.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_rsa_private_key (1 of 2 overloads)]
+
+
+Use an RSA private key from a memory buffer.
+
+
+ void use_rsa_private_key(
+ const const_buffer & private_key,
+ file_format format);
+
+
+This function is used to load an RSA private key into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[private_key][The buffer containing the RSA private key.]]
+
+[[format][The private key format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_RSAPrivateKey` or SSL\_CTX\_use\_RSAPrivateKey\_ASN1.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_rsa_private_key (2 of 2 overloads)]
+
+
+Use an RSA private key from a memory buffer.
+
+
+ void use_rsa_private_key(
+ const const_buffer & private_key,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load an RSA private key into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[private_key][The buffer containing the RSA private key.]]
+
+[[format][The private key format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_RSAPrivateKey` or SSL\_CTX\_use\_RSAPrivateKey\_ASN1.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_rsa_private_key_file ssl::context::use_rsa_private_key_file]
+
+[indexterm2 asio.indexterm.ssl__context.use_rsa_private_key_file..use_rsa_private_key_file..ssl::context]
+Use an RSA private key from a file.
+
+
+ void ``[link asio.reference.ssl__context.use_rsa_private_key_file.overload1 use_rsa_private_key_file]``(
+ const std::string & filename,
+ file_format format);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_rsa_private_key_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_rsa_private_key_file.overload2 use_rsa_private_key_file]``(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_rsa_private_key_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_rsa_private_key_file (1 of 2 overloads)]
+
+
+Use an RSA private key from a file.
+
+
+ void use_rsa_private_key_file(
+ const std::string & filename,
+ file_format format);
+
+
+This function is used to load an RSA private key into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the RSA private key.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_RSAPrivateKey_file`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_rsa_private_key_file (2 of 2 overloads)]
+
+
+Use an RSA private key from a file.
+
+
+ void use_rsa_private_key_file(
+ const std::string & filename,
+ file_format format,
+ asio::error_code & ec);
+
+
+This function is used to load an RSA private key into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the RSA private key.]]
+
+[[format][The file format (ASN.1 or PEM).]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_use_RSAPrivateKey_file`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_tmp_dh ssl::context::use_tmp_dh]
+
+[indexterm2 asio.indexterm.ssl__context.use_tmp_dh..use_tmp_dh..ssl::context]
+Use the specified memory buffer to obtain the temporary Diffie-Hellman parameters.
+
+
+ void ``[link asio.reference.ssl__context.use_tmp_dh.overload1 use_tmp_dh]``(
+ const const_buffer & dh);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_tmp_dh.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_tmp_dh.overload2 use_tmp_dh]``(
+ const const_buffer & dh,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_tmp_dh.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_tmp_dh (1 of 2 overloads)]
+
+
+Use the specified memory buffer to obtain the temporary Diffie-Hellman parameters.
+
+
+ void use_tmp_dh(
+ const const_buffer & dh);
+
+
+This function is used to load Diffie-Hellman parameters into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[dh][The memory buffer containing the Diffie-Hellman parameters. The buffer must use the PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_tmp_dh`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_tmp_dh (2 of 2 overloads)]
+
+
+Use the specified memory buffer to obtain the temporary Diffie-Hellman parameters.
+
+
+ void use_tmp_dh(
+ const const_buffer & dh,
+ asio::error_code & ec);
+
+
+This function is used to load Diffie-Hellman parameters into the context from a buffer.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[dh][The memory buffer containing the Diffie-Hellman parameters. The buffer must use the PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_tmp_dh`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_tmp_dh_file ssl::context::use_tmp_dh_file]
+
+[indexterm2 asio.indexterm.ssl__context.use_tmp_dh_file..use_tmp_dh_file..ssl::context]
+Use the specified file to obtain the temporary Diffie-Hellman parameters.
+
+
+ void ``[link asio.reference.ssl__context.use_tmp_dh_file.overload1 use_tmp_dh_file]``(
+ const std::string & filename);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_tmp_dh_file.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__context.use_tmp_dh_file.overload2 use_tmp_dh_file]``(
+ const std::string & filename,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__context.use_tmp_dh_file.overload2 more...]]``
+
+
+[section:overload1 ssl::context::use_tmp_dh_file (1 of 2 overloads)]
+
+
+Use the specified file to obtain the temporary Diffie-Hellman parameters.
+
+
+ void use_tmp_dh_file(
+ const std::string & filename);
+
+
+This function is used to load Diffie-Hellman parameters into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the Diffie-Hellman parameters. The file must use the PEM format.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_tmp_dh`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::context::use_tmp_dh_file (2 of 2 overloads)]
+
+
+Use the specified file to obtain the temporary Diffie-Hellman parameters.
+
+
+ void use_tmp_dh_file(
+ const std::string & filename,
+ asio::error_code & ec);
+
+
+This function is used to load Diffie-Hellman parameters into the context from a file.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[filename][The name of the file containing the Diffie-Hellman parameters. The file must use the PEM format.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_CTX_set_tmp_dh`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_context ssl::context::~context]
+
+[indexterm2 asio.indexterm.ssl__context._context..~context..ssl::context]
+Destructor.
+
+
+ ~context();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ssl__context_base ssl::context_base]
+
+
+The [link asio.reference.ssl__context_base `ssl::context_base`] class is used as a base for the basic\_context class template so that we have a common place to define various enums.
+
+
+ class context_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__context_base.file_format [*file_format]]]
+ [File format types. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context_base.method [*method]]]
+ [Different methods supported by a context. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context_base.options [*options]]]
+ [Bitmask type for SSL options. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__context_base.password_purpose [*password_purpose]]]
+ [Purpose of PEM password. ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__context_base._context_base [*~context_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__context_base.default_workarounds [*default_workarounds]]]
+ [Implement various bug workarounds. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_compression [*no_compression]]]
+ [Disable compression. Compression is disabled by default. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_sslv2 [*no_sslv2]]]
+ [Disable SSL v2. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_sslv3 [*no_sslv3]]]
+ [Disable SSL v3. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_tlsv1 [*no_tlsv1]]]
+ [Disable TLS v1. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_tlsv1_1 [*no_tlsv1_1]]]
+ [Disable TLS v1.1. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.no_tlsv1_2 [*no_tlsv1_2]]]
+ [Disable TLS v1.2. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__context_base.single_dh_use [*single_dh_use]]]
+ [Always create a new key when using tmp_dh parameters. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/context_base.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[section:default_workarounds ssl::context_base::default_workarounds]
+
+[indexterm2 asio.indexterm.ssl__context_base.default_workarounds..default_workarounds..ssl::context_base]
+Implement various bug workarounds.
+
+
+ static const long default_workarounds = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:file_format ssl::context_base::file_format]
+
+[indexterm2 asio.indexterm.ssl__context_base.file_format..file_format..ssl::context_base]
+File format types.
+
+
+ enum file_format
+
+[indexterm2 asio.indexterm.ssl__context_base.file_format.asn1..asn1..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.file_format.pem..pem..ssl::context_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [asn1]
+ [ASN.1 file. ]
+ ]
+
+ [
+ [pem]
+ [PEM file. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:method ssl::context_base::method]
+
+[indexterm2 asio.indexterm.ssl__context_base.method..method..ssl::context_base]
+Different methods supported by a context.
+
+
+ enum method
+
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv2..sslv2..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv2_client..sslv2_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv2_server..sslv2_server..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv3..sslv3..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv3_client..sslv3_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv3_server..sslv3_server..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv1..tlsv1..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv1_client..tlsv1_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv1_server..tlsv1_server..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv23..sslv23..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv23_client..sslv23_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.sslv23_server..sslv23_server..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv11..tlsv11..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv11_client..tlsv11_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv11_server..tlsv11_server..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv12..tlsv12..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv12_client..tlsv12_client..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.method.tlsv12_server..tlsv12_server..ssl::context_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [sslv2]
+ [Generic SSL version 2. ]
+ ]
+
+ [
+ [sslv2_client]
+ [SSL version 2 client. ]
+ ]
+
+ [
+ [sslv2_server]
+ [SSL version 2 server. ]
+ ]
+
+ [
+ [sslv3]
+ [Generic SSL version 3. ]
+ ]
+
+ [
+ [sslv3_client]
+ [SSL version 3 client. ]
+ ]
+
+ [
+ [sslv3_server]
+ [SSL version 3 server. ]
+ ]
+
+ [
+ [tlsv1]
+ [Generic TLS version 1. ]
+ ]
+
+ [
+ [tlsv1_client]
+ [TLS version 1 client. ]
+ ]
+
+ [
+ [tlsv1_server]
+ [TLS version 1 server. ]
+ ]
+
+ [
+ [sslv23]
+ [Generic SSL/TLS. ]
+ ]
+
+ [
+ [sslv23_client]
+ [SSL/TLS client. ]
+ ]
+
+ [
+ [sslv23_server]
+ [SSL/TLS server. ]
+ ]
+
+ [
+ [tlsv11]
+ [Generic TLS version 1.1. ]
+ ]
+
+ [
+ [tlsv11_client]
+ [TLS version 1.1 client. ]
+ ]
+
+ [
+ [tlsv11_server]
+ [TLS version 1.1 server. ]
+ ]
+
+ [
+ [tlsv12]
+ [Generic TLS version 1.2. ]
+ ]
+
+ [
+ [tlsv12_client]
+ [TLS version 1.2 client. ]
+ ]
+
+ [
+ [tlsv12_server]
+ [TLS version 1.2 server. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:no_compression ssl::context_base::no_compression]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_compression..no_compression..ssl::context_base]
+Disable compression. Compression is disabled by default.
+
+
+ static const long no_compression = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_sslv2 ssl::context_base::no_sslv2]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_sslv2..no_sslv2..ssl::context_base]
+Disable SSL v2.
+
+
+ static const long no_sslv2 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_sslv3 ssl::context_base::no_sslv3]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_sslv3..no_sslv3..ssl::context_base]
+Disable SSL v3.
+
+
+ static const long no_sslv3 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1 ssl::context_base::no_tlsv1]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_tlsv1..no_tlsv1..ssl::context_base]
+Disable TLS v1.
+
+
+ static const long no_tlsv1 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1_1 ssl::context_base::no_tlsv1_1]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_tlsv1_1..no_tlsv1_1..ssl::context_base]
+Disable TLS v1.1.
+
+
+ static const long no_tlsv1_1 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:no_tlsv1_2 ssl::context_base::no_tlsv1_2]
+
+[indexterm2 asio.indexterm.ssl__context_base.no_tlsv1_2..no_tlsv1_2..ssl::context_base]
+Disable TLS v1.2.
+
+
+ static const long no_tlsv1_2 = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:options ssl::context_base::options]
+
+[indexterm2 asio.indexterm.ssl__context_base.options..options..ssl::context_base]
+Bitmask type for SSL options.
+
+
+ typedef long options;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/context_base.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:password_purpose ssl::context_base::password_purpose]
+
+[indexterm2 asio.indexterm.ssl__context_base.password_purpose..password_purpose..ssl::context_base]
+Purpose of PEM password.
+
+
+ enum password_purpose
+
+[indexterm2 asio.indexterm.ssl__context_base.password_purpose.for_reading..for_reading..ssl::context_base]
+[indexterm2 asio.indexterm.ssl__context_base.password_purpose.for_writing..for_writing..ssl::context_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [for_reading]
+ [The password is needed for reading/decryption. ]
+ ]
+
+ [
+ [for_writing]
+ [The password is needed for writing/encryption. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:single_dh_use ssl::context_base::single_dh_use]
+
+[indexterm2 asio.indexterm.ssl__context_base.single_dh_use..single_dh_use..ssl::context_base]
+Always create a new key when using tmp\_dh parameters.
+
+
+ static const long single_dh_use = implementation_defined;
+
+
+
+[endsect]
+
+
+
+[section:_context_base ssl::context_base::~context_base]
+
+[indexterm2 asio.indexterm.ssl__context_base._context_base..~context_base..ssl::context_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~context_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ssl__error__get_stream_category ssl::error::get_stream_category]
+
+[indexterm1 asio.indexterm.ssl__error__get_stream_category..ssl::error::get_stream_category]
+
+ const asio::error_category & get_stream_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__error__make_error_code ssl::error::make_error_code]
+
+[indexterm1 asio.indexterm.ssl__error__make_error_code..ssl::error::make_error_code]
+
+ asio::error_code make_error_code(
+ stream_errors e);
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__error__stream_category ssl::error::stream_category]
+
+[indexterm1 asio.indexterm.ssl__error__stream_category..ssl::error::stream_category]
+
+ static const asio::error_category & stream_category = asio::ssl::error::get_stream_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__error__stream_errors ssl::error::stream_errors]
+
+[indexterm1 asio.indexterm.ssl__error__stream_errors..ssl::error::stream_errors]
+
+ enum stream_errors
+
+[indexterm2 asio.indexterm.ssl__error__stream_errors.stream_truncated..stream_truncated..ssl::error::stream_errors]
+
+[heading Values]
+[variablelist
+
+ [
+ [stream_truncated]
+ [The underlying stream closed before the ssl stream gracefully shut down. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/error.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+[section:ssl__rfc2818_verification ssl::rfc2818_verification]
+
+
+Verifies a certificate against a hostname according to the rules described in RFC 2818.
+
+
+ class rfc2818_verification
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__rfc2818_verification.result_type [*result_type]]]
+ [The type of the function object's result. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__rfc2818_verification.operator_lp__rp_ [*operator()]]]
+ [Perform certificate verification. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__rfc2818_verification.rfc2818_verification [*rfc2818_verification]]]
+ [Constructor. ]
+ ]
+
+]
+
+
+[heading Example]
+
+The following example shows how to synchronously open a secure connection to a given host name:
+
+ using asio::ip::tcp;
+ namespace ssl = asio::ssl;
+ typedef ssl::stream<tcp::socket> ssl_socket;
+
+ // Create a context that uses the default paths for finding CA certificates.
+ ssl::context ctx(ssl::context::sslv23);
+ ctx.set_default_verify_paths();
+
+ // Open a socket and connect it to the remote host.
+ asio::io_context io_context;
+ ssl_socket sock(io_context, ctx);
+ tcp::resolver resolver(io_context);
+ tcp::resolver::query query("host.name", "https");
+ asio::connect(sock.lowest_layer(), resolver.resolve(query));
+ sock.lowest_layer().set_option(tcp::no_delay(true));
+
+ // Perform SSL handshake and verify the remote host's certificate.
+ sock.set_verify_mode(ssl::verify_peer);
+ sock.set_verify_callback(ssl::rfc2818_verification("host.name"));
+ sock.handshake(ssl_socket::client);
+
+ // ... read and write as normal ...
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/rfc2818_verification.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[section:operator_lp__rp_ ssl::rfc2818_verification::operator()]
+
+[indexterm2 asio.indexterm.ssl__rfc2818_verification.operator_lp__rp_..operator()..ssl::rfc2818_verification]
+Perform certificate verification.
+
+
+ bool operator()(
+ bool preverified,
+ verify_context & ctx) const;
+
+
+
+[endsect]
+
+
+
+[section:result_type ssl::rfc2818_verification::result_type]
+
+[indexterm2 asio.indexterm.ssl__rfc2818_verification.result_type..result_type..ssl::rfc2818_verification]
+The type of the function object's result.
+
+
+ typedef bool result_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/rfc2818_verification.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:rfc2818_verification ssl::rfc2818_verification::rfc2818_verification]
+
+[indexterm2 asio.indexterm.ssl__rfc2818_verification.rfc2818_verification..rfc2818_verification..ssl::rfc2818_verification]
+Constructor.
+
+
+ rfc2818_verification(
+ const std::string & host);
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ssl__stream ssl::stream]
+
+
+Provides stream-oriented functionality using SSL.
+
+
+ template<
+ typename Stream>
+ class stream :
+ public ssl::stream_base,
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__stream__impl_struct [*impl_struct]]]
+ [Structure for use with deprecated impl_type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__stream.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__stream.handshake_type [*handshake_type]]]
+ [Different handshake types. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__stream.lowest_layer_type [*lowest_layer_type]]]
+ [The type of the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__stream.native_handle_type [*native_handle_type]]]
+ [The native handle type of the SSL stream. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.ssl__stream.next_layer_type [*next_layer_type]]]
+ [The type of the next layer. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__stream.async_handshake [*async_handshake]]]
+ [Start an asynchronous SSL handshake. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.async_shutdown [*async_shutdown]]]
+ [Asynchronously shut down SSL on the stream. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.handshake [*handshake]]]
+ [Perform SSL handshaking. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.native_handle [*native_handle]]]
+ [Get the underlying implementation in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.next_layer [*next_layer]]]
+ [Get a reference to the next layer. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.read_some [*read_some]]]
+ [Read some data from the stream. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.set_verify_callback [*set_verify_callback]]]
+ [Set the callback used to verify peer certificates. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.set_verify_depth [*set_verify_depth]]]
+ [Set the peer verification depth. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.set_verify_mode [*set_verify_mode]]]
+ [Set the peer verification mode. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.shutdown [*shutdown]]]
+ [Shut down SSL on the stream. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.stream [*stream]]]
+ [Construct a stream. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream.write_some [*write_some]]]
+ [Write some data to the stream. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__stream._stream [*~stream]]]
+ [Destructor. ]
+ ]
+
+]
+
+The stream class template provides asynchronous and blocking stream-oriented functionality using SSL.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe. The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand.
+
+
+[heading Example]
+
+To use the SSL stream template with an `ip::tcp::socket`, you would write:
+
+ asio::io_context io_context;
+ asio::ssl::context ctx(asio::ssl::context::sslv23);
+ asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+[section:async_handshake ssl::stream::async_handshake]
+
+[indexterm2 asio.indexterm.ssl__stream.async_handshake..async_handshake..ssl::stream]
+Start an asynchronous SSL handshake.
+
+
+ template<
+ typename ``[link asio.reference.HandshakeHandler HandshakeHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ssl__stream.async_handshake.overload1 async_handshake]``(
+ handshake_type type,
+ HandshakeHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.async_handshake.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.BufferedHandshakeHandler BufferedHandshakeHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` ``[link asio.reference.ssl__stream.async_handshake.overload2 async_handshake]``(
+ handshake_type type,
+ const ConstBufferSequence & buffers,
+ BufferedHandshakeHandler && handler);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.async_handshake.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::async_handshake (1 of 2 overloads)]
+
+
+Start an asynchronous SSL handshake.
+
+
+ template<
+ typename ``[link asio.reference.HandshakeHandler HandshakeHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_handshake(
+ handshake_type type,
+ HandshakeHandler && handler);
+
+
+This function is used to asynchronously perform an SSL handshake on the stream. This function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+[[handler][The handler to be called when the handshake operation completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::async_handshake (2 of 2 overloads)]
+
+
+Start an asynchronous SSL handshake.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.BufferedHandshakeHandler BufferedHandshakeHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_handshake(
+ handshake_type type,
+ const ConstBufferSequence & buffers,
+ BufferedHandshakeHandler && handler);
+
+
+This function is used to asynchronously perform an SSL handshake on the stream. This function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+[[buffers][The buffered data to be reused for the handshake. Although the buffers object may be copied as necessary, ownership of the underlying buffers is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the handshake operation completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Amount of buffers used in handshake.
+ );
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_read_some ssl::stream::async_read_some]
+
+[indexterm2 asio.indexterm.ssl__stream.async_read_some..async_read_some..ssl::stream]
+Start an asynchronous read.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read one or more bytes of data from the stream. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying buffers is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+]]
+
+]
+
+
+[heading Remarks]
+
+The async\_read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+
+
+[endsect]
+
+
+
+[section:async_shutdown ssl::stream::async_shutdown]
+
+[indexterm2 asio.indexterm.ssl__stream.async_shutdown..async_shutdown..ssl::stream]
+Asynchronously shut down SSL on the stream.
+
+
+ template<
+ typename ``[link asio.reference.ShutdownHandler ShutdownHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_shutdown(
+ ShutdownHandler && handler);
+
+
+This function is used to asynchronously shut down SSL on the stream. This function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called when the handshake operation completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some ssl::stream::async_write_some]
+
+[indexterm2 asio.indexterm.ssl__stream.async_write_some..async_write_some..ssl::stream]
+Start an asynchronous write.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write one or more bytes of data to the stream. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The data to be written to the stream. Although the buffers object may be copied as necessary, ownership of the underlying buffers is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+]]
+
+]
+
+
+[heading Remarks]
+
+The async\_write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+
+[section:executor_type ssl::stream::executor_type]
+
+[indexterm2 asio.indexterm.ssl__stream.executor_type..executor_type..ssl::stream]
+The type of the executor associated with the object.
+
+
+ typedef lowest_layer_type::executor_type executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor ssl::stream::get_executor]
+
+[indexterm2 asio.indexterm.ssl__stream.get_executor..get_executor..ssl::stream]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+This function may be used to obtain the executor object that the stream uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A copy of the executor that stream will use to dispatch handlers.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_context ssl::stream::get_io_context]
+
+[indexterm2 asio.indexterm.ssl__stream.get_io_context..get_io_context..ssl::stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+
+[endsect]
+
+
+
+[section:get_io_service ssl::stream::get_io_service]
+
+[indexterm2 asio.indexterm.ssl__stream.get_io_service..get_io_service..ssl::stream]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+
+[endsect]
+
+
+[section:handshake ssl::stream::handshake]
+
+[indexterm2 asio.indexterm.ssl__stream.handshake..handshake..ssl::stream]
+Perform SSL handshaking.
+
+
+ void ``[link asio.reference.ssl__stream.handshake.overload1 handshake]``(
+ handshake_type type);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.handshake.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__stream.handshake.overload2 handshake]``(
+ handshake_type type,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.handshake.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ void ``[link asio.reference.ssl__stream.handshake.overload3 handshake]``(
+ handshake_type type,
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.handshake.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ void ``[link asio.reference.ssl__stream.handshake.overload4 handshake]``(
+ handshake_type type,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.handshake.overload4 more...]]``
+
+
+[section:overload1 ssl::stream::handshake (1 of 4 overloads)]
+
+
+Perform SSL handshaking.
+
+
+ void handshake(
+ handshake_type type);
+
+
+This function is used to perform SSL handshaking on the stream. The function call will block until handshaking is complete or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::handshake (2 of 4 overloads)]
+
+
+Perform SSL handshaking.
+
+
+ void handshake(
+ handshake_type type,
+ asio::error_code & ec);
+
+
+This function is used to perform SSL handshaking on the stream. The function call will block until handshaking is complete or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 ssl::stream::handshake (3 of 4 overloads)]
+
+
+Perform SSL handshaking.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ void handshake(
+ handshake_type type,
+ const ConstBufferSequence & buffers);
+
+
+This function is used to perform SSL handshaking on the stream. The function call will block until handshaking is complete or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+[[buffers][The buffered data to be reused for the handshake.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 ssl::stream::handshake (4 of 4 overloads)]
+
+
+Perform SSL handshaking.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ void handshake(
+ handshake_type type,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to perform SSL handshaking on the stream. The function call will block until handshaking is complete or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[type][The type of handshaking to be performed, i.e. as a client or as a server.]]
+
+[[buffers][The buffered data to be reused for the handshake.]]
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:handshake_type ssl::stream::handshake_type]
+
+[indexterm2 asio.indexterm.ssl__stream.handshake_type..handshake_type..ssl::stream]
+Different handshake types.
+
+
+ enum handshake_type
+
+[indexterm2 asio.indexterm.ssl__stream.handshake_type.client..client..ssl::stream]
+[indexterm2 asio.indexterm.ssl__stream.handshake_type.server..server..ssl::stream]
+
+[heading Values]
+[variablelist
+
+ [
+ [client]
+ [Perform handshaking as a client. ]
+ ]
+
+ [
+ [server]
+ [Perform handshaking as a server. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+[section:lowest_layer ssl::stream::lowest_layer]
+
+[indexterm2 asio.indexterm.ssl__stream.lowest_layer..lowest_layer..ssl::stream]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.ssl__stream.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.lowest_layer.overload1 more...]]``
+
+ const lowest_layer_type & ``[link asio.reference.ssl__stream.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of stream layers.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of stream layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::lowest_layer (2 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a reference to the lowest layer in a stack of stream layers.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of stream layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type ssl::stream::lowest_layer_type]
+
+[indexterm2 asio.indexterm.ssl__stream.lowest_layer_type..lowest_layer_type..ssl::stream]
+The type of the lowest layer.
+
+
+ typedef next_layer_type::lowest_layer_type lowest_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle ssl::stream::native_handle]
+
+[indexterm2 asio.indexterm.ssl__stream.native_handle..native_handle..ssl::stream]
+Get the underlying implementation in the native type.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying implementation of the context. This is intended to allow access to context functionality that is not otherwise provided.
+
+
+[heading Example]
+
+The `native_handle()` function returns a pointer of type `SSL*` that is suitable for passing to functions such as `SSL_get_verify_result` and `SSL_get_peer_certificate:`
+
+ asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+
+ // ... establish connection and perform handshake ...
+
+ if (X509* cert = SSL_get_peer_certificate(sock.native_handle()))
+ {
+ if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK)
+ {
+ // ...
+ }
+ }
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:native_handle_type ssl::stream::native_handle_type]
+
+[indexterm2 asio.indexterm.ssl__stream.native_handle_type..native_handle_type..ssl::stream]
+The native handle type of the SSL stream.
+
+
+ typedef SSL * native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+[section:next_layer ssl::stream::next_layer]
+
+[indexterm2 asio.indexterm.ssl__stream.next_layer..next_layer..ssl::stream]
+Get a reference to the next layer.
+
+
+ const next_layer_type & ``[link asio.reference.ssl__stream.next_layer.overload1 next_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.next_layer.overload1 more...]]``
+
+ next_layer_type & ``[link asio.reference.ssl__stream.next_layer.overload2 next_layer]``();
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.next_layer.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::next_layer (1 of 2 overloads)]
+
+
+Get a reference to the next layer.
+
+
+ const next_layer_type & next_layer() const;
+
+
+This function returns a reference to the next layer in a stack of stream layers.
+
+
+[heading Return Value]
+
+A reference to the next layer in the stack of stream layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::next_layer (2 of 2 overloads)]
+
+
+Get a reference to the next layer.
+
+
+ next_layer_type & next_layer();
+
+
+This function returns a reference to the next layer in a stack of stream layers.
+
+
+[heading Return Value]
+
+A reference to the next layer in the stack of stream layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:next_layer_type ssl::stream::next_layer_type]
+
+[indexterm2 asio.indexterm.ssl__stream.next_layer_type..next_layer_type..ssl::stream]
+The type of the next layer.
+
+
+ typedef remove_reference< Stream >::type next_layer_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+[section:read_some ssl::stream::read_some]
+
+[indexterm2 asio.indexterm.ssl__stream.read_some..read_some..ssl::stream]
+Read some data from the stream.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.ssl__stream.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.read_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.ssl__stream.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.read_some.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::read_some (1 of 2 overloads)]
+
+
+Read some data from the stream.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the stream. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::read_some (2 of 2 overloads)]
+
+
+Read some data from the stream.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the stream. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_callback ssl::stream::set_verify_callback]
+
+[indexterm2 asio.indexterm.ssl__stream.set_verify_callback..set_verify_callback..ssl::stream]
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void ``[link asio.reference.ssl__stream.set_verify_callback.overload1 set_verify_callback]``(
+ VerifyCallback callback);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_callback.overload1 more...]]``
+
+ template<
+ typename VerifyCallback>
+ void ``[link asio.reference.ssl__stream.set_verify_callback.overload2 set_verify_callback]``(
+ VerifyCallback callback,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_callback.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::set_verify_callback (1 of 2 overloads)]
+
+
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void set_verify_callback(
+ VerifyCallback callback);
+
+
+This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
+``
+ bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ verify_context& ctx // The peer certificate and other context.
+ );
+``
+The return value of the callback is true if the certificate has passed verification, false otherwise.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::set_verify_callback (2 of 2 overloads)]
+
+
+Set the callback used to verify peer certificates.
+
+
+ template<
+ typename VerifyCallback>
+ void set_verify_callback(
+ VerifyCallback callback,
+ asio::error_code & ec);
+
+
+This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
+``
+ bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ verify_context& ctx // The peer certificate and other context.
+ );
+``
+The return value of the callback is true if the certificate has passed verification, false otherwise.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_depth ssl::stream::set_verify_depth]
+
+[indexterm2 asio.indexterm.ssl__stream.set_verify_depth..set_verify_depth..ssl::stream]
+Set the peer verification depth.
+
+
+ void ``[link asio.reference.ssl__stream.set_verify_depth.overload1 set_verify_depth]``(
+ int depth);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_depth.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__stream.set_verify_depth.overload2 set_verify_depth]``(
+ int depth,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_depth.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::set_verify_depth (1 of 2 overloads)]
+
+
+Set the peer verification depth.
+
+
+ void set_verify_depth(
+ int depth);
+
+
+This function may be used to configure the maximum verification depth allowed by the stream.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[depth][Maximum depth for the certificate chain verification that shall be allowed.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify_depth`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::set_verify_depth (2 of 2 overloads)]
+
+
+Set the peer verification depth.
+
+
+ void set_verify_depth(
+ int depth,
+ asio::error_code & ec);
+
+
+This function may be used to configure the maximum verification depth allowed by the stream.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[depth][Maximum depth for the certificate chain verification that shall be allowed.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify_depth`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:set_verify_mode ssl::stream::set_verify_mode]
+
+[indexterm2 asio.indexterm.ssl__stream.set_verify_mode..set_verify_mode..ssl::stream]
+Set the peer verification mode.
+
+
+ void ``[link asio.reference.ssl__stream.set_verify_mode.overload1 set_verify_mode]``(
+ verify_mode v);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_mode.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__stream.set_verify_mode.overload2 set_verify_mode]``(
+ verify_mode v,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_mode.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::set_verify_mode (1 of 2 overloads)]
+
+
+Set the peer verification mode.
+
+
+ void set_verify_mode(
+ verify_mode v);
+
+
+This function may be used to configure the peer verification mode used by the stream. The new mode will override the mode inherited from the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::set_verify_mode (2 of 2 overloads)]
+
+
+Set the peer verification mode.
+
+
+ void set_verify_mode(
+ verify_mode v,
+ asio::error_code & ec);
+
+
+This function may be used to configure the peer verification mode used by the stream. The new mode will override the mode inherited from the context.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Remarks]
+
+Calls `SSL_set_verify`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:shutdown ssl::stream::shutdown]
+
+[indexterm2 asio.indexterm.ssl__stream.shutdown..shutdown..ssl::stream]
+Shut down SSL on the stream.
+
+
+ void ``[link asio.reference.ssl__stream.shutdown.overload1 shutdown]``();
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.shutdown.overload1 more...]]``
+
+ void ``[link asio.reference.ssl__stream.shutdown.overload2 shutdown]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.shutdown.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::shutdown (1 of 2 overloads)]
+
+
+Shut down SSL on the stream.
+
+
+ void shutdown();
+
+
+This function is used to shut down SSL on the stream. The function call will block until SSL has been shut down or an error occurs.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::shutdown (2 of 2 overloads)]
+
+
+Shut down SSL on the stream.
+
+
+ void shutdown(
+ asio::error_code & ec);
+
+
+This function is used to shut down SSL on the stream. The function call will block until SSL has been shut down or an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:stream ssl::stream::stream]
+
+[indexterm2 asio.indexterm.ssl__stream.stream..stream..ssl::stream]
+Construct a stream.
+
+
+ template<
+ typename Arg>
+ stream(
+ Arg && arg,
+ context & ctx);
+
+
+This constructor creates a stream and initialises the underlying stream object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[arg][The argument to be passed to initialise the underlying stream.]]
+
+[[ctx][The SSL context to be used for the stream. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:write_some ssl::stream::write_some]
+
+[indexterm2 asio.indexterm.ssl__stream.write_some..write_some..ssl::stream]
+Write some data to the stream.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.ssl__stream.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.write_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.ssl__stream.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.ssl__stream.write_some.overload2 more...]]``
+
+
+[section:overload1 ssl::stream::write_some (1 of 2 overloads)]
+
+
+Write some data to the stream.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data on the stream. The function call will block until one or more bytes of data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The data to be written.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 ssl::stream::write_some (2 of 2 overloads)]
+
+
+Write some data to the stream.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data on the stream. The function call will block until one or more bytes of data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][The data to be written to the stream.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_stream ssl::stream::~stream]
+
+[indexterm2 asio.indexterm.ssl__stream._stream..~stream..ssl::stream]
+Destructor.
+
+
+ ~stream();
+
+
+
+[heading Remarks]
+
+A `stream` object must not be destroyed while there are pending asynchronous operations associated with it.
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ssl__stream__impl_struct ssl::stream::impl_struct]
+
+
+Structure for use with deprecated impl\_type.
+
+
+ struct impl_struct
+
+
+[heading Data Members]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__stream__impl_struct.ssl [*ssl]]]
+ []
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[section:ssl ssl::stream::impl_struct::ssl]
+
+[indexterm2 asio.indexterm.ssl__stream__impl_struct.ssl..ssl..ssl::stream::impl_struct]
+
+ SSL * ssl;
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:ssl__stream_base ssl::stream_base]
+
+
+The [link asio.reference.ssl__stream_base `ssl::stream_base`] class is used as a base for the [link asio.reference.ssl__stream `ssl::stream`] class template so that we have a common place to define various enums.
+
+
+ class stream_base
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__stream_base.handshake_type [*handshake_type]]]
+ [Different handshake types. ]
+
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__stream_base._stream_base [*~stream_base]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/stream_base.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[section:handshake_type ssl::stream_base::handshake_type]
+
+[indexterm2 asio.indexterm.ssl__stream_base.handshake_type..handshake_type..ssl::stream_base]
+Different handshake types.
+
+
+ enum handshake_type
+
+[indexterm2 asio.indexterm.ssl__stream_base.handshake_type.client..client..ssl::stream_base]
+[indexterm2 asio.indexterm.ssl__stream_base.handshake_type.server..server..ssl::stream_base]
+
+[heading Values]
+[variablelist
+
+ [
+ [client]
+ [Perform handshaking as a client. ]
+ ]
+
+ [
+ [server]
+ [Perform handshaking as a server. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:_stream_base ssl::stream_base::~stream_base]
+
+[indexterm2 asio.indexterm.ssl__stream_base._stream_base..~stream_base..ssl::stream_base]
+Protected destructor to prevent deletion through this type.
+
+
+ ~stream_base();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ssl__verify_client_once ssl::verify_client_once]
+
+[indexterm1 asio.indexterm.ssl__verify_client_once..ssl::verify_client_once]
+Do not request client certificate on renegotiation. Ignored unless [link asio.reference.ssl__verify_peer `ssl::verify_peer`] is set.
+
+
+ const int verify_client_once = implementation_defined;
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_mode.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+[section:ssl__verify_context ssl::verify_context]
+
+
+A simple wrapper around the X509\_STORE\_CTX type, used during verification of a peer certificate.
+
+
+ class verify_context :
+ noncopyable
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.ssl__verify_context.native_handle_type [*native_handle_type]]]
+ [The native handle type of the verification context. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.ssl__verify_context.native_handle [*native_handle]]]
+ [Get the underlying implementation in the native type. ]
+ ]
+
+ [
+ [[link asio.reference.ssl__verify_context.verify_context [*verify_context]]]
+ [Constructor. ]
+ ]
+
+]
+
+
+[heading Remarks]
+
+The [link asio.reference.ssl__verify_context `ssl::verify_context`] does not own the underlying X509\_STORE\_CTX object.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_context.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[section:native_handle ssl::verify_context::native_handle]
+
+[indexterm2 asio.indexterm.ssl__verify_context.native_handle..native_handle..ssl::verify_context]
+Get the underlying implementation in the native type.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying implementation of the context. This is intended to allow access to context functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type ssl::verify_context::native_handle_type]
+
+[indexterm2 asio.indexterm.ssl__verify_context.native_handle_type..native_handle_type..ssl::verify_context]
+The native handle type of the verification context.
+
+
+ typedef X509_STORE_CTX * native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_context.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:verify_context ssl::verify_context::verify_context]
+
+[indexterm2 asio.indexterm.ssl__verify_context.verify_context..verify_context..ssl::verify_context]
+Constructor.
+
+
+ verify_context(
+ native_handle_type handle);
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:ssl__verify_fail_if_no_peer_cert ssl::verify_fail_if_no_peer_cert]
+
+[indexterm1 asio.indexterm.ssl__verify_fail_if_no_peer_cert..ssl::verify_fail_if_no_peer_cert]
+Fail verification if the peer has no certificate. Ignored unless [link asio.reference.ssl__verify_peer `ssl::verify_peer`] is set.
+
+
+ const int verify_fail_if_no_peer_cert = implementation_defined;
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_mode.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__verify_mode ssl::verify_mode]
+
+[indexterm1 asio.indexterm.ssl__verify_mode..ssl::verify_mode]
+Bitmask type for peer verification.
+
+
+ typedef int verify_mode;
+
+
+
+Possible values are:
+
+
+* [link asio.reference.ssl__verify_none `ssl::verify_none`]
+
+* [link asio.reference.ssl__verify_peer `ssl::verify_peer`]
+
+* [link asio.reference.ssl__verify_fail_if_no_peer_cert `ssl::verify_fail_if_no_peer_cert`]
+
+* [link asio.reference.ssl__verify_client_once `ssl::verify_client_once`]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_mode.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__verify_none ssl::verify_none]
+
+[indexterm1 asio.indexterm.ssl__verify_none..ssl::verify_none]
+No verification.
+
+
+ const int verify_none = implementation_defined;
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_mode.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:ssl__verify_peer ssl::verify_peer]
+
+[indexterm1 asio.indexterm.ssl__verify_peer..ssl::verify_peer]
+Verify the peer.
+
+
+ const int verify_peer = implementation_defined;
+
+
+[heading Requirements]
+
+['Header: ][^asio/ssl/verify_mode.hpp]
+
+['Convenience header: ][^asio/ssl.hpp]
+
+
+[endsect]
+
+
+
+[section:steady_timer steady_timer]
+
+[indexterm1 asio.indexterm.steady_timer..steady_timer]
+Typedef for a timer based on the steady clock.
+
+
+ typedef basic_waitable_timer< chrono::steady_clock > steady_timer;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.duration [*duration]]]
+ [The duration type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.time_point [*time_point]]]
+ [The time point type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.traits_type [*traits_type]]]
+ [The wait traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_waitable_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.basic_waitable_timer [*basic_waitable_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_after [*expires_after]]]
+ [Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time.
+
+ (Deprecated: Use non-error_code overload.) Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expiry [*expiry]]]
+ [Get the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer._basic_waitable_timer [*~basic_waitable_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_waitable_timer `basic_waitable_timer`] class template provides the ability to perform a blocking or asynchronous wait for a timer to expire.
+
+A waitable 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 one of the [link asio.reference.steady_timer `steady_timer`], [link asio.reference.system_timer `system_timer`] or [link asio.reference.high_resolution_timer `high_resolution_timer`] typedefs.
+
+
+[heading Remarks]
+
+This waitable timer functionality is for use with the C++11 standard library's `<chrono>` facility, or with the Boost.Chrono library.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait (C++11):
+
+ // Construct a timer without setting an expiry time.
+ asio::steady_timer timer(io_context);
+
+ // Set an expiry time relative to now.
+ timer.expires_after(std::chrono::seconds(5));
+
+ // Wait for the timer to expire.
+ timer.wait();
+
+
+
+
+
+Performing an asynchronous wait (C++11):
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::steady_timer timer(io_context,
+ std::chrono::steady_clock::now() + std::chrono::seconds(60));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading Changing an active waitable 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:
+
+
+
+ void on_some_event()
+ {
+ if (my_timer.expires_after(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.
+ }
+ }
+
+
+
+
+
+* The `asio::basic_waitable_timer::expires_after()` 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+
+This typedef uses the C++11 `<chrono>` standard library facility, if available. Otherwise, it may use the Boost.Chrono library. To explicitly utilise Boost.Chrono, use the [link asio.reference.basic_waitable_timer `basic_waitable_timer`] template directly:
+
+ typedef basic_waitable_timer<boost::chrono::steady_clock> timer;
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/steady_timer.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+[section:strand strand]
+
+
+Provides serialised function invocation for any executor type.
+
+
+ template<
+ typename ``[link asio.reference.Executor1 Executor]``>
+ class strand
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.strand.inner_executor_type [*inner_executor_type]]]
+ [The type of the underlying executor. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.strand.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.strand.defer [*defer]]]
+ [Request the strand to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.strand.dispatch [*dispatch]]]
+ [Request the strand to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.strand.get_inner_executor [*get_inner_executor]]]
+ [Obtain the underlying executor. ]
+ ]
+
+ [
+ [[link asio.reference.strand.on_work_finished [*on_work_finished]]]
+ [Inform the strand that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.strand.on_work_started [*on_work_started]]]
+ [Inform the strand that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.strand.operator_eq_ [*operator=]]]
+ [Assignment operator.
+
+ Converting assignment operator.
+
+ Move assignment operator.
+
+ Converting move assignment operator. ]
+ ]
+
+ [
+ [[link asio.reference.strand.post [*post]]]
+ [Request the strand to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.strand.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the strand is running in the current thread. ]
+ ]
+
+ [
+ [[link asio.reference.strand.strand [*strand]]]
+ [Default constructor.
+
+ Construct a strand for the specified executor.
+
+ Copy constructor.
+
+ Converting constructor.
+
+ Move constructor.
+
+ Converting move constructor. ]
+ ]
+
+ [
+ [[link asio.reference.strand._strand [*~strand]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.strand.operator_not__eq_ [*operator!=]]]
+ [Compare two strands for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.strand.operator_eq__eq_ [*operator==]]]
+ [Compare two strands for equality. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context strand::context]
+
+[indexterm2 asio.indexterm.strand.context..context..strand]
+Obtain the underlying execution context.
+
+
+ execution_context & context();
+
+
+
+[endsect]
+
+
+
+[section:defer strand::defer]
+
+[indexterm2 asio.indexterm.strand.defer..defer..strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled by the underlying executor's defer function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch strand::dispatch]
+
+[indexterm2 asio.indexterm.strand.dispatch..dispatch..strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the strand to execute the given function object on its underlying executor. The function object will be executed inside this function if the strand is not otherwise busy and if the underlying executor's `dispatch()` function is also able to execute the function before returning.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:get_inner_executor strand::get_inner_executor]
+
+[indexterm2 asio.indexterm.strand.get_inner_executor..get_inner_executor..strand]
+Obtain the underlying executor.
+
+
+ inner_executor_type get_inner_executor() const;
+
+
+
+[endsect]
+
+
+
+[section:inner_executor_type strand::inner_executor_type]
+
+[indexterm2 asio.indexterm.strand.inner_executor_type..inner_executor_type..strand]
+The type of the underlying executor.
+
+
+ typedef Executor inner_executor_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:on_work_finished strand::on_work_finished]
+
+[indexterm2 asio.indexterm.strand.on_work_finished..on_work_finished..strand]
+Inform the strand that some work is no longer outstanding.
+
+
+ void on_work_finished();
+
+
+The strand delegates this call to its underlying executor.
+
+
+[endsect]
+
+
+
+[section:on_work_started strand::on_work_started]
+
+[indexterm2 asio.indexterm.strand.on_work_started..on_work_started..strand]
+Inform the strand that it has some outstanding work to do.
+
+
+ void on_work_started();
+
+
+The strand delegates this call to its underlying executor.
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ strand::operator!=]
+
+[indexterm2 asio.indexterm.strand.operator_not__eq_..operator!=..strand]
+Compare two strands for inequality.
+
+
+ friend bool operator!=(
+ const strand & a,
+ const strand & b);
+
+
+Two strands are equal if they refer to the same ordered, non-concurrent state.
+
+[heading Requirements]
+
+['Header: ][^asio/strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:operator_eq_ strand::operator=]
+
+[indexterm2 asio.indexterm.strand.operator_eq_..operator=..strand]
+Assignment operator.
+
+
+ strand & ``[link asio.reference.strand.operator_eq_.overload1 operator=]``(
+ const strand & other);
+ `` [''''&raquo;''' [link asio.reference.strand.operator_eq_.overload1 more...]]``
+
+
+Converting assignment operator.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand & ``[link asio.reference.strand.operator_eq_.overload2 operator=]``(
+ const strand< OtherExecutor > & other);
+ `` [''''&raquo;''' [link asio.reference.strand.operator_eq_.overload2 more...]]``
+
+
+Move assignment operator.
+
+
+ strand & ``[link asio.reference.strand.operator_eq_.overload3 operator=]``(
+ strand && other);
+ `` [''''&raquo;''' [link asio.reference.strand.operator_eq_.overload3 more...]]``
+
+
+Converting move assignment operator.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand & ``[link asio.reference.strand.operator_eq_.overload4 operator=]``(
+ const strand< OtherExecutor > && other);
+ `` [''''&raquo;''' [link asio.reference.strand.operator_eq_.overload4 more...]]``
+
+
+[section:overload1 strand::operator= (1 of 4 overloads)]
+
+
+Assignment operator.
+
+
+ strand & operator=(
+ const strand & other);
+
+
+
+[endsect]
+
+
+
+[section:overload2 strand::operator= (2 of 4 overloads)]
+
+
+Converting assignment operator.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand & operator=(
+ const strand< OtherExecutor > & other);
+
+
+This assignment operator is only valid if the `OtherExecutor` type is convertible to `Executor`.
+
+
+[endsect]
+
+
+
+[section:overload3 strand::operator= (3 of 4 overloads)]
+
+
+Move assignment operator.
+
+
+ strand & operator=(
+ strand && other);
+
+
+
+[endsect]
+
+
+
+[section:overload4 strand::operator= (4 of 4 overloads)]
+
+
+Converting move assignment operator.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand & operator=(
+ const strand< OtherExecutor > && other);
+
+
+This assignment operator is only valid if the `OtherExecutor` type is convertible to `Executor`.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq__eq_ strand::operator==]
+
+[indexterm2 asio.indexterm.strand.operator_eq__eq_..operator==..strand]
+Compare two strands for equality.
+
+
+ friend bool operator==(
+ const strand & a,
+ const strand & b);
+
+
+Two strands are equal if they refer to the same ordered, non-concurrent state.
+
+[heading Requirements]
+
+['Header: ][^asio/strand.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:post strand::post]
+
+[indexterm2 asio.indexterm.strand.post..post..strand]
+Request the strand to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a);
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled by the underlying executor's defer function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:running_in_this_thread strand::running_in_this_thread]
+
+[indexterm2 asio.indexterm.strand.running_in_this_thread..running_in_this_thread..strand]
+Determine whether the strand is running in the current thread.
+
+
+ bool running_in_this_thread() const;
+
+
+
+[heading Return Value]
+
+`true` if the current thread is executing a function that was submitted to the strand using `post()`, `dispatch()` or `defer()`. Otherwise returns `false`.
+
+
+
+
+[endsect]
+
+
+[section:strand strand::strand]
+
+[indexterm2 asio.indexterm.strand.strand..strand..strand]
+Default constructor.
+
+
+ ``[link asio.reference.strand.strand.overload1 strand]``();
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload1 more...]]``
+
+
+Construct a strand for the specified executor.
+
+
+ explicit ``[link asio.reference.strand.strand.overload2 strand]``(
+ const Executor & e);
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.strand.strand.overload3 strand]``(
+ const strand & other);
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload3 more...]]``
+
+
+Converting constructor.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.strand.strand.overload4 strand]``(
+ const strand< OtherExecutor > & other);
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload4 more...]]``
+
+
+Move constructor.
+
+
+ ``[link asio.reference.strand.strand.overload5 strand]``(
+ strand && other);
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload5 more...]]``
+
+
+Converting move constructor.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ ``[link asio.reference.strand.strand.overload6 strand]``(
+ strand< OtherExecutor > && other);
+ `` [''''&raquo;''' [link asio.reference.strand.strand.overload6 more...]]``
+
+
+[section:overload1 strand::strand (1 of 6 overloads)]
+
+
+Default constructor.
+
+
+ strand();
+
+
+This constructor is only valid if the underlying executor type is default constructible.
+
+
+[endsect]
+
+
+
+[section:overload2 strand::strand (2 of 6 overloads)]
+
+
+Construct a strand for the specified executor.
+
+
+ strand(
+ const Executor & e);
+
+
+
+[endsect]
+
+
+
+[section:overload3 strand::strand (3 of 6 overloads)]
+
+
+Copy constructor.
+
+
+ strand(
+ const strand & other);
+
+
+
+[endsect]
+
+
+
+[section:overload4 strand::strand (4 of 6 overloads)]
+
+
+Converting constructor.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand(
+ const strand< OtherExecutor > & other);
+
+
+This constructor is only valid if the `OtherExecutor` type is convertible to `Executor`.
+
+
+[endsect]
+
+
+
+[section:overload5 strand::strand (5 of 6 overloads)]
+
+
+Move constructor.
+
+
+ strand(
+ strand && other);
+
+
+
+[endsect]
+
+
+
+[section:overload6 strand::strand (6 of 6 overloads)]
+
+
+Converting move constructor.
+
+
+ template<
+ class ``[link asio.reference.Executor1 OtherExecutor]``>
+ strand(
+ strand< OtherExecutor > && other);
+
+
+This constructor is only valid if the `OtherExecutor` type is convertible to `Executor`.
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_strand strand::~strand]
+
+[indexterm2 asio.indexterm.strand._strand..~strand..strand]
+Destructor.
+
+
+ ~strand();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:streambuf streambuf]
+
+[indexterm1 asio.indexterm.streambuf..streambuf]
+Typedef for the typical usage of [link asio.reference.basic_streambuf `basic_streambuf`].
+
+
+ typedef basic_streambuf streambuf;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_streambuf.const_buffers_type [*const_buffers_type]]]
+ [The type used to represent the input sequence as a list of buffers. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_streambuf.mutable_buffers_type [*mutable_buffers_type]]]
+ [The type used to represent the output sequence as a list of buffers. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.basic_streambuf [*basic_streambuf]]]
+ [Construct a basic_streambuf object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.capacity [*capacity]]]
+ [Get the current capacity of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.commit [*commit]]]
+ [Move characters from the output sequence to the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.consume [*consume]]]
+ [Remove characters from the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.data [*data]]]
+ [Get a list of buffers that represents the input sequence. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.max_size [*max_size]]]
+ [Get the maximum size of the basic_streambuf. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.prepare [*prepare]]]
+ [Get a list of buffers that represents the output sequence, with the given size. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.size [*size]]]
+ [Get the size of the input sequence. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_streambuf.overflow [*overflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.reserve [*reserve]]]
+ []
+ ]
+
+ [
+ [[link asio.reference.basic_streambuf.underflow [*underflow]]]
+ [Override std::streambuf behaviour. ]
+ ]
+
+]
+
+The `basic_streambuf` class is derived from `std::streambuf` to associate the streambuf's input and output sequences with one or more character arrays. These character arrays are internal to the `basic_streambuf` object, but direct access to the array elements is provided to permit them to be used efficiently with I/O operations. Characters written to the output sequence of a `basic_streambuf` object are appended to the input sequence of the same object.
+
+The `basic_streambuf` class's public interface is intended to permit the following implementation strategies:
+
+
+* A single contiguous character array, which is reallocated as necessary to accommodate changes in the size of the character sequence. This is the implementation approach currently used in Asio.
+
+
+* A sequence of one or more character arrays, where each array is of the same size. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+
+* A sequence of one or more character arrays of varying sizes. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.
+
+The constructor for [link asio.reference.basic_streambuf `basic_streambuf`] accepts a `size_t` argument specifying the maximum of the sum of the sizes of the input sequence and output sequence. During the lifetime of the `basic_streambuf` object, the following invariant holds:
+
+ size() <= max_size()
+
+
+Any member function that would, if successful, cause the invariant to be violated shall throw an exception of class `std::length_error`.
+
+The constructor for `basic_streambuf` takes an Allocator argument. A copy of this argument is used for any memory allocation performed, by the constructor and by all member functions, during the lifetime of each `basic_streambuf` object.
+
+
+[heading Examples]
+
+Writing directly from an streambuf to a socket:
+
+ asio::streambuf b;
+ std::ostream os(&b);
+ os << "Hello, World!\n";
+
+ // try sending some data in input sequence
+ size_t n = sock.send(b.data());
+
+ b.consume(n); // sent data is removed from input sequence
+
+
+
+
+Reading from a socket directly into a streambuf:
+
+ asio::streambuf b;
+
+ // reserve 512 bytes in output sequence
+ asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
+
+ size_t n = sock.receive(bufs);
+
+ // received data is "committed" from output sequence to input sequence
+ b.commit(n);
+
+ std::istream is(&b);
+ std::string s;
+ is >> s;
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/streambuf.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:system_category system_category]
+
+[indexterm1 asio.indexterm.system_category..system_category]
+Returns the error category used for the system errors produced by asio.
+
+
+ const error_category & system_category();
+
+
+[heading Requirements]
+
+['Header: ][^asio/error_code.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:system_error system_error]
+
+
+The [link asio.reference.system_error `system_error`] class is used to represent system conditions that prevent the library from operating correctly.
+
+
+ class system_error :
+ public std::exception
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.system_error.code [*code]]]
+ [Get the error code associated with the exception. ]
+ ]
+
+ [
+ [[link asio.reference.system_error.operator_eq_ [*operator=]]]
+ [Assignment operator. ]
+ ]
+
+ [
+ [[link asio.reference.system_error.system_error [*system_error]]]
+ [Construct with an error code.
+
+ Construct with an error code and context.
+
+ Copy constructor. ]
+ ]
+
+ [
+ [[link asio.reference.system_error.what [*what]]]
+ [Get a string representation of the exception. ]
+ ]
+
+ [
+ [[link asio.reference.system_error._system_error [*~system_error]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/system_error.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:code system_error::code]
+
+[indexterm2 asio.indexterm.system_error.code..code..system_error]
+Get the error code associated with the exception.
+
+
+ error_code code() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_eq_ system_error::operator=]
+
+[indexterm2 asio.indexterm.system_error.operator_eq_..operator=..system_error]
+Assignment operator.
+
+
+ system_error & operator=(
+ const system_error & e);
+
+
+
+[endsect]
+
+
+[section:system_error system_error::system_error]
+
+[indexterm2 asio.indexterm.system_error.system_error..system_error..system_error]
+Construct with an error code.
+
+
+ ``[link asio.reference.system_error.system_error.overload1 system_error]``(
+ const error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.system_error.system_error.overload1 more...]]``
+
+
+Construct with an error code and context.
+
+
+ ``[link asio.reference.system_error.system_error.overload2 system_error]``(
+ const error_code & ec,
+ const std::string & context);
+ `` [''''&raquo;''' [link asio.reference.system_error.system_error.overload2 more...]]``
+
+
+Copy constructor.
+
+
+ ``[link asio.reference.system_error.system_error.overload3 system_error]``(
+ const system_error & other);
+ `` [''''&raquo;''' [link asio.reference.system_error.system_error.overload3 more...]]``
+
+
+[section:overload1 system_error::system_error (1 of 3 overloads)]
+
+
+Construct with an error code.
+
+
+ system_error(
+ const error_code & ec);
+
+
+
+[endsect]
+
+
+
+[section:overload2 system_error::system_error (2 of 3 overloads)]
+
+
+Construct with an error code and context.
+
+
+ system_error(
+ const error_code & ec,
+ const std::string & context);
+
+
+
+[endsect]
+
+
+
+[section:overload3 system_error::system_error (3 of 3 overloads)]
+
+
+Copy constructor.
+
+
+ system_error(
+ const system_error & other);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:what system_error::what]
+
+[indexterm2 asio.indexterm.system_error.what..what..system_error]
+Get a string representation of the exception.
+
+
+ virtual const char * what() const;
+
+
+
+[endsect]
+
+
+
+[section:_system_error system_error::~system_error]
+
+[indexterm2 asio.indexterm.system_error._system_error..~system_error..system_error]
+Destructor.
+
+
+ virtual ~system_error();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:system_executor system_executor]
+
+
+An executor that uses arbitrary threads.
+
+
+ class system_executor
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.system_executor.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.defer [*defer]]]
+ [Request the system executor to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.dispatch [*dispatch]]]
+ [Request the system executor to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.on_work_finished [*on_work_finished]]]
+ [Inform the executor that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.on_work_started [*on_work_started]]]
+ [Inform the executor that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.post [*post]]]
+ [Request the system executor to invoke the given function object. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.system_executor.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.system_executor.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+The system executor represents an execution context where functions are permitted to run on arbitrary threads. The `post()` and `defer()` functions schedule the function to run on an unspecified system thread pool, and `dispatch()` invokes the function immediately.
+
+[heading Requirements]
+
+['Header: ][^asio/system_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context system_executor::context]
+
+[indexterm2 asio.indexterm.system_executor.context..context..system_executor]
+Obtain the underlying execution context.
+
+
+ execution_context & context() const;
+
+
+
+[endsect]
+
+
+
+[section:defer system_executor::defer]
+
+[indexterm2 asio.indexterm.system_executor.defer..defer..system_executor]
+Request the system executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled to run on an unspecified system thread pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch system_executor::dispatch]
+
+[indexterm2 asio.indexterm.system_executor.dispatch..dispatch..system_executor]
+Request the system executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object will always be executed inside this function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:on_work_finished system_executor::on_work_finished]
+
+[indexterm2 asio.indexterm.system_executor.on_work_finished..on_work_finished..system_executor]
+Inform the executor that some work is no longer outstanding.
+
+
+ void on_work_finished() const;
+
+
+For the system executor, this is a no-op.
+
+
+[endsect]
+
+
+
+[section:on_work_started system_executor::on_work_started]
+
+[indexterm2 asio.indexterm.system_executor.on_work_started..on_work_started..system_executor]
+Inform the executor that it has some outstanding work to do.
+
+
+ void on_work_started() const;
+
+
+For the system executor, this is a no-op.
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ system_executor::operator!=]
+
+[indexterm2 asio.indexterm.system_executor.operator_not__eq_..operator!=..system_executor]
+Compare two executors for inequality.
+
+
+ friend bool operator!=(
+ const system_executor & ,
+ const system_executor & );
+
+
+System executors always compare equal.
+
+[heading Requirements]
+
+['Header: ][^asio/system_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ system_executor::operator==]
+
+[indexterm2 asio.indexterm.system_executor.operator_eq__eq_..operator==..system_executor]
+Compare two executors for equality.
+
+
+ friend bool operator==(
+ const system_executor & ,
+ const system_executor & );
+
+
+System executors always compare equal.
+
+[heading Requirements]
+
+['Header: ][^asio/system_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:post system_executor::post]
+
+[indexterm2 asio.indexterm.system_executor.post..post..system_executor]
+Request the system executor to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the executor to execute the given function object. The function object will never be executed inside this function. Instead, it will be scheduled to run on an unspecified system thread pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:system_timer system_timer]
+
+[indexterm1 asio.indexterm.system_timer..system_timer]
+Typedef for a timer based on the system clock.
+
+
+ typedef basic_waitable_timer< chrono::system_clock > system_timer;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.clock_type [*clock_type]]]
+ [The clock type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.duration [*duration]]]
+ [The duration type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.time_point [*time_point]]]
+ [The time point type of the clock. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_waitable_timer.traits_type [*traits_type]]]
+ [The wait traits type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_waitable_timer.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.basic_waitable_timer [*basic_waitable_timer]]]
+ [Constructor.
+
+ Constructor to set a particular expiry time as an absolute time.
+
+ Constructor to set a particular expiry time relative to now.
+
+ Move-construct a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel [*cancel]]]
+ [Cancel any asynchronous operations that are waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancel any asynchronous operations that are waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.cancel_one [*cancel_one]]]
+ [Cancels one asynchronous operation that is waiting on the timer.
+
+ (Deprecated: Use non-error_code overload.) Cancels one asynchronous operation that is waiting on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_after [*expires_after]]]
+ [Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_at [*expires_at]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time as an absolute time.
+
+ Set the timer's expiry time as an absolute time.
+
+ (Deprecated: Use non-error_code overload.) Set the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expires_from_now [*expires_from_now]]]
+ [(Deprecated: Use expiry().) Get the timer's expiry time relative to now.
+
+ (Deprecated: Use expires_after().) Set the timer's expiry time relative to now. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.expiry [*expiry]]]
+ [Get the timer's expiry time as an absolute time. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.operator_eq_ [*operator=]]]
+ [Move-assign a basic_waitable_timer from another. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer.wait [*wait]]]
+ [Perform a blocking wait on the timer. ]
+ ]
+
+ [
+ [[link asio.reference.basic_waitable_timer._basic_waitable_timer [*~basic_waitable_timer]]]
+ [Destroys the timer. ]
+ ]
+
+]
+
+The [link asio.reference.basic_waitable_timer `basic_waitable_timer`] class template provides the ability to perform a blocking or asynchronous wait for a timer to expire.
+
+A waitable 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 one of the [link asio.reference.steady_timer `steady_timer`], [link asio.reference.system_timer `system_timer`] or [link asio.reference.high_resolution_timer `high_resolution_timer`] typedefs.
+
+
+[heading Remarks]
+
+This waitable timer functionality is for use with the C++11 standard library's `<chrono>` facility, or with the Boost.Chrono library.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Examples]
+
+Performing a blocking wait (C++11):
+
+ // Construct a timer without setting an expiry time.
+ asio::steady_timer timer(io_context);
+
+ // Set an expiry time relative to now.
+ timer.expires_after(std::chrono::seconds(5));
+
+ // Wait for the timer to expire.
+ timer.wait();
+
+
+
+
+
+Performing an asynchronous wait (C++11):
+
+ void handler(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Timer expired.
+ }
+ }
+
+ ...
+
+ // Construct a timer with an absolute expiry time.
+ asio::steady_timer timer(io_context,
+ std::chrono::steady_clock::now() + std::chrono::seconds(60));
+
+ // Start an asynchronous wait.
+ timer.async_wait(handler);
+
+
+
+
+
+[heading Changing an active waitable 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:
+
+
+
+ void on_some_event()
+ {
+ if (my_timer.expires_after(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.
+ }
+ }
+
+
+
+
+
+* The `asio::basic_waitable_timer::expires_after()` 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.
+
+
+* If a wait handler is cancelled, the [link asio.reference.error_code `error_code`] passed to it contains the value `asio::error::operation_aborted`.
+
+
+
+
+This typedef uses the C++11 `<chrono>` standard library facility, if available. Otherwise, it may use the Boost.Chrono library. To explicitly utilise Boost.Chrono, use the [link asio.reference.basic_waitable_timer `basic_waitable_timer`] template directly:
+
+ typedef basic_waitable_timer<boost::chrono::system_clock> timer;
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/system_timer.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+[section:thread thread]
+
+
+A simple abstraction for starting threads.
+
+
+ class thread :
+ noncopyable
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread.join [*join]]]
+ [Wait for the thread to exit. ]
+ ]
+
+ [
+ [[link asio.reference.thread.thread [*thread]]]
+ [Start a new thread that executes the supplied function. ]
+ ]
+
+ [
+ [[link asio.reference.thread._thread [*~thread]]]
+ [Destructor. ]
+ ]
+
+]
+
+The [link asio.reference.thread `thread`] class implements the smallest possible subset of the functionality of boost::thread. It is intended to be used only for starting a thread and waiting for it to exit. If more extensive threading capabilities are required, you are strongly advised to use something else.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+[heading Example]
+
+A typical use of [link asio.reference.thread `thread`] would be to launch a thread to run an io\_context's event processing loop:
+
+
+
+
+ asio::io_context io_context;
+ // ...
+ asio::thread t(boost::bind(&asio::io_context::run, &io_context));
+ // ...
+ t.join();
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:join thread::join]
+
+[indexterm2 asio.indexterm.thread.join..join..thread]
+Wait for the thread to exit.
+
+
+ void join();
+
+
+This function will block until the thread has exited.
+
+If this function is not called before the thread object is destroyed, the thread itself will continue to run until completion. You will, however, no longer have the ability to wait for it to exit.
+
+
+[endsect]
+
+
+
+[section:thread thread::thread]
+
+[indexterm2 asio.indexterm.thread.thread..thread..thread]
+Start a new thread that executes the supplied function.
+
+
+ template<
+ typename Function>
+ thread(
+ Function f);
+
+
+This constructor creates a new thread that will execute the given function or function object.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function or function object to be run in the thread. The function signature must be:
+``
+ void f();
+``
+]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:_thread thread::~thread]
+
+[indexterm2 asio.indexterm.thread._thread..~thread..thread]
+Destructor.
+
+
+ ~thread();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:thread_pool thread_pool]
+
+
+A simple fixed-size thread pool.
+
+
+ class thread_pool :
+ public execution_context
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.thread_pool__executor_type [*executor_type]]]
+ [Executor used to submit functions to a thread pool. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.thread_pool.fork_event [*fork_event]]]
+ [Fork-related event notifications. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread_pool.get_executor [*get_executor]]]
+ [Obtains the executor associated with the pool. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.join [*join]]]
+ [Joins the threads. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.notify_fork [*notify_fork]]]
+ [Notify the execution_context of a fork-related event. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.stop [*stop]]]
+ [Stops the threads. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.thread_pool [*thread_pool]]]
+ [Constructs a pool with an automatically determined number of threads.
+
+ Constructs a pool with a specified number of threads. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool._thread_pool [*~thread_pool]]]
+ [Destructor. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread_pool.destroy [*destroy]]]
+ [Destroys all services in the context. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.shutdown [*shutdown]]]
+ [Shuts down all services in the context. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread_pool.add_service [*add_service]]]
+ [(Deprecated: Use make_service().) Add a service object to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.has_service [*has_service]]]
+ [Determine if an execution_context contains a specified service type. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.make_service [*make_service]]]
+ [Creates a service object and adds it to the execution_context. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool.use_service [*use_service]]]
+ [Obtain the service object corresponding to the given type. ]
+ ]
+
+]
+
+The thread pool class is an execution context where functions are permitted to run on one of a fixed number of threads.
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:add_service thread_pool::add_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.add_service..add_service..thread_pool]
+(Deprecated: Use `make_service()`.) Add a service object to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend void add_service(
+ execution_context & e,
+ Service * svc);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[svc][The service object. On success, ownership of the service object is transferred to the [link asio.reference.execution_context `execution_context`]. When the [link asio.reference.execution_context `execution_context`] object is destroyed, it will destroy the service object by performing:
+``
+ delete static_cast<execution_context::service*>(svc)
+``
+]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`].]]
+
+[[asio::invalid_service_owner][Thrown if the service's owning [link asio.reference.execution_context `execution_context`] is not the [link asio.reference.execution_context `execution_context`] object specified by the `e` parameter. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:destroy thread_pool::destroy]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.destroy..destroy..thread_pool]
+Destroys all services in the context.
+
+
+ void destroy();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order * of the beginning of service object lifetime, performs `delete static_cast<execution_context::service*>(svc)`.
+
+
+
+
+[endsect]
+
+
+
+[section:fork_event thread_pool::fork_event]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.fork_event..fork_event..thread_pool]
+Fork-related event notifications.
+
+
+ enum fork_event
+
+[indexterm2 asio.indexterm.thread_pool.fork_event.fork_prepare..fork_prepare..thread_pool]
+[indexterm2 asio.indexterm.thread_pool.fork_event.fork_parent..fork_parent..thread_pool]
+[indexterm2 asio.indexterm.thread_pool.fork_event.fork_child..fork_child..thread_pool]
+
+[heading Values]
+[variablelist
+
+ [
+ [fork_prepare]
+ [Notify the context that the process is about to fork. ]
+ ]
+
+ [
+ [fork_parent]
+ [Notify the context that the process has forked and is the parent. ]
+ ]
+
+ [
+ [fork_child]
+ [Notify the context that the process has forked and is the child. ]
+ ]
+
+]
+
+
+
+[endsect]
+
+
+
+[section:get_executor thread_pool::get_executor]
+
+[indexterm2 asio.indexterm.thread_pool.get_executor..get_executor..thread_pool]
+Obtains the executor associated with the pool.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:has_service thread_pool::has_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.has_service..has_service..thread_pool]
+Determine if an [link asio.reference.execution_context `execution_context`] contains a specified service type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend bool has_service(
+ execution_context & e);
+
+
+This function is used to determine whether the [link asio.reference.execution_context `execution_context`] contains a service object corresponding to the given service type.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+A boolean indicating whether the [link asio.reference.execution_context `execution_context`] contains the service.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:join thread_pool::join]
+
+[indexterm2 asio.indexterm.thread_pool.join..join..thread_pool]
+Joins the threads.
+
+
+ void join();
+
+
+This function blocks until the threads in the pool have completed. If `stop()` is not called prior to `join()`, the `join()` call will wait until the pool has no more outstanding work.
+
+
+[endsect]
+
+
+
+[section:make_service thread_pool::make_service]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.make_service..make_service..thread_pool]
+Creates a service object and adds it to the [link asio.reference.execution_context `execution_context`].
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``,
+ typename... Args>
+ friend Service & make_service(
+ execution_context & e,
+ Args &&... args);
+
+
+This function is used to add a service to the [link asio.reference.execution_context `execution_context`].
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+[[args][Zero or more arguments to be passed to the service constructor.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::service_already_exists][Thrown if a service of the given type is already present in the [link asio.reference.execution_context `execution_context`]. ]]
+
+]
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:notify_fork thread_pool::notify_fork]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.notify_fork..notify_fork..thread_pool]
+Notify the [link asio.reference.execution_context `execution_context`] of a fork-related event.
+
+
+ void notify_fork(
+ fork_event event);
+
+
+This function is used to inform the [link asio.reference.execution_context `execution_context`] that the process is about to fork, or has just forked. This allows the [link asio.reference.execution_context `execution_context`], and the services it contains, to perform any necessary housekeeping to ensure correct operation following a fork.
+
+This function must not be called while any other [link asio.reference.execution_context `execution_context`] function, or any function associated with the execution\_context's derived class, is being called in another thread. It is, however, safe to call this function from within a completion handler, provided no other thread is accessing the [link asio.reference.execution_context `execution_context`] or its derived class.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[event][A fork-related event.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. If the notification fails the [link asio.reference.execution_context `execution_context`] object should no longer be used and should be destroyed.]]
+
+]
+
+
+[heading Example]
+
+The following code illustrates how to incorporate the `notify_fork()` function:
+
+ my_execution_context.notify_fork(execution_context::fork_prepare);
+ if (fork() == 0)
+ {
+ // This is the child process.
+ my_execution_context.notify_fork(execution_context::fork_child);
+ }
+ else
+ {
+ // This is the parent process.
+ my_execution_context.notify_fork(execution_context::fork_parent);
+ }
+
+
+
+
+
+[heading Remarks]
+
+For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, performs `svc->notify_fork();`. When processing the fork\_prepare event, services are visited in reverse order of the beginning of service object lifetime. Otherwise, services are visited in order of the beginning of service object lifetime.
+
+
+
+
+[endsect]
+
+
+
+[section:shutdown thread_pool::shutdown]
+
+
+['Inherited from execution_context.]
+
+[indexterm2 asio.indexterm.thread_pool.shutdown..shutdown..thread_pool]
+Shuts down all services in the context.
+
+
+ void shutdown();
+
+
+This function is implemented as follows:
+
+
+* For each service object `svc` in the [link asio.reference.execution_context `execution_context`] set, in reverse order of the beginning of service object lifetime, performs `svc->shutdown()`.
+
+
+
+
+[endsect]
+
+
+
+[section:stop thread_pool::stop]
+
+[indexterm2 asio.indexterm.thread_pool.stop..stop..thread_pool]
+Stops the threads.
+
+
+ void stop();
+
+
+This function stops the threads as soon as possible. As a result of calling `stop()`, pending function objects may be never be invoked.
+
+
+[endsect]
+
+
+[section:thread_pool thread_pool::thread_pool]
+
+[indexterm2 asio.indexterm.thread_pool.thread_pool..thread_pool..thread_pool]
+Constructs a pool with an automatically determined number of threads.
+
+
+ ``[link asio.reference.thread_pool.thread_pool.overload1 thread_pool]``();
+ `` [''''&raquo;''' [link asio.reference.thread_pool.thread_pool.overload1 more...]]``
+
+
+Constructs a pool with a specified number of threads.
+
+
+ ``[link asio.reference.thread_pool.thread_pool.overload2 thread_pool]``(
+ std::size_t num_threads);
+ `` [''''&raquo;''' [link asio.reference.thread_pool.thread_pool.overload2 more...]]``
+
+
+[section:overload1 thread_pool::thread_pool (1 of 2 overloads)]
+
+
+Constructs a pool with an automatically determined number of threads.
+
+
+ thread_pool();
+
+
+
+[endsect]
+
+
+
+[section:overload2 thread_pool::thread_pool (2 of 2 overloads)]
+
+
+Constructs a pool with a specified number of threads.
+
+
+ thread_pool(
+ std::size_t num_threads);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_service thread_pool::use_service]
+
+[indexterm2 asio.indexterm.thread_pool.use_service..use_service..thread_pool]
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.thread_pool.use_service.overload1 use_service]``(
+ execution_context & e);
+ `` [''''&raquo;''' [link asio.reference.thread_pool.use_service.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & ``[link asio.reference.thread_pool.use_service.overload2 use_service]``(
+ io_context & ioc);
+ `` [''''&raquo;''' [link asio.reference.thread_pool.use_service.overload2 more...]]``
+
+
+[section:overload1 thread_pool::use_service (1 of 2 overloads)]
+
+
+['Inherited from execution_context.]
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ execution_context & e);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.execution_context `execution_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:overload2 thread_pool::use_service (2 of 2 overloads)]
+
+
+['Inherited from execution_context.]
+
+
+Obtain the service object corresponding to the given type.
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ friend Service & use_service(
+ io_context & ioc);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.io_context `io_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ioc][The [link asio.reference.io_context `io_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+[heading Remarks]
+
+This overload is preserved for backwards compatibility with services that inherit from [link asio.reference.io_context__service `io_context::service`].
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_thread_pool thread_pool::~thread_pool]
+
+[indexterm2 asio.indexterm.thread_pool._thread_pool..~thread_pool..thread_pool]
+Destructor.
+
+
+ ~thread_pool();
+
+
+Automatically stops and joins the pool, if not explicitly done beforehand.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:thread_pool__executor_type thread_pool::executor_type]
+
+
+Executor used to submit functions to a thread pool.
+
+
+ class executor_type
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.defer [*defer]]]
+ [Request the thread pool to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.dispatch [*dispatch]]]
+ [Request the thread pool to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the thread pool that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.on_work_started [*on_work_started]]]
+ [Inform the thread pool that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.post [*post]]]
+ [Request the thread pool to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the thread pool is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.thread_pool__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:context thread_pool::executor_type::context]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.context..context..thread_pool::executor_type]
+Obtain the underlying execution context.
+
+
+ thread_pool & context() const;
+
+
+
+[endsect]
+
+
+
+[section:defer thread_pool::executor_type::defer]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.defer..defer..thread_pool::executor_type]
+Request the thread pool to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void defer(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the thread pool to execute the given function object. The function object will never be executed inside `defer()`. Instead, it will be scheduled to run on the thread pool.
+
+If the current thread belongs to the thread pool, `defer()` will delay scheduling the function object until the current thread returns control to the pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:dispatch thread_pool::executor_type::dispatch]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.dispatch..dispatch..thread_pool::executor_type]
+Request the thread pool to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void dispatch(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the thread pool to execute the given function object. If the current thread belongs to the pool, `dispatch()` executes the function before returning. Otherwise, the function will be scheduled to run on the thread pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:on_work_finished thread_pool::executor_type::on_work_finished]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.on_work_finished..on_work_finished..thread_pool::executor_type]
+Inform the thread pool that some work is no longer outstanding.
+
+
+ void on_work_finished() const;
+
+
+This function is used to inform the thread pool that some work has finished. Once the count of unfinished work reaches zero, the thread pool's `join()` function is permitted to exit.
+
+
+[endsect]
+
+
+
+[section:on_work_started thread_pool::executor_type::on_work_started]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.on_work_started..on_work_started..thread_pool::executor_type]
+Inform the thread pool that it has some outstanding work to do.
+
+
+ void on_work_started() const;
+
+
+This function is used to inform the thread pool that some work has begun. This ensures that the thread pool's `join()` function will not return while the work is underway.
+
+
+[endsect]
+
+
+
+[section:operator_not__eq_ thread_pool::executor_type::operator!=]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.operator_not__eq_..operator!=..thread_pool::executor_type]
+Compare two executors for inequality.
+
+
+ friend bool operator!=(
+ const executor_type & a,
+ const executor_type & b);
+
+
+Two executors are equal if they refer to the same underlying thread pool.
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq__eq_ thread_pool::executor_type::operator==]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.operator_eq__eq_..operator==..thread_pool::executor_type]
+Compare two executors for equality.
+
+
+ friend bool operator==(
+ const executor_type & a,
+ const executor_type & b);
+
+
+Two executors are equal if they refer to the same underlying thread pool.
+
+[heading Requirements]
+
+['Header: ][^asio/thread_pool.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:post thread_pool::executor_type::post]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.post..post..thread_pool::executor_type]
+Request the thread pool to invoke the given function object.
+
+
+ template<
+ typename Function,
+ typename Allocator>
+ void post(
+ Function && f,
+ const Allocator & a) const;
+
+
+This function is used to ask the thread pool to execute the given function object. The function object will never be executed inside `post()`. Instead, it will be scheduled to run on the thread pool.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[f][The function object to be called. The executor will make a copy of the handler object as required. The function signature of the function object must be:
+``
+ void function();
+``
+]]
+
+[[a][An allocator that may be used by the executor to allocate the internal storage needed for function invocation. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:running_in_this_thread thread_pool::executor_type::running_in_this_thread]
+
+[indexterm2 asio.indexterm.thread_pool__executor_type.running_in_this_thread..running_in_this_thread..thread_pool::executor_type]
+Determine whether the thread pool is running in the current thread.
+
+
+ bool running_in_this_thread() const;
+
+
+
+[heading Return Value]
+
+`true` if the current thread belongs to the pool. Otherwise returns `false`.
+
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:time_traits_lt__ptime__gt_ time_traits< boost::posix_time::ptime >]
+
+
+Time traits specialised for posix\_time.
+
+
+ template<>
+ struct time_traits< boost::posix_time::ptime >
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.time_traits_lt__ptime__gt_.duration_type [*duration_type]]]
+ [The duration type. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.time_traits_lt__ptime__gt_.time_type [*time_type]]]
+ [The time type. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.time_traits_lt__ptime__gt_.add [*add]]]
+ [Add a duration to a time. ]
+ ]
+
+ [
+ [[link asio.reference.time_traits_lt__ptime__gt_.less_than [*less_than]]]
+ [Test whether one time is less than another. ]
+ ]
+
+ [
+ [[link asio.reference.time_traits_lt__ptime__gt_.now [*now]]]
+ [Get the current time. ]
+ ]
+
+ [
+ [[link asio.reference.time_traits_lt__ptime__gt_.subtract [*subtract]]]
+ [Subtract one time from another. ]
+ ]
+
+ [
+ [[link asio.reference.time_traits_lt__ptime__gt_.to_posix_duration [*to_posix_duration]]]
+ [Convert to POSIX duration type. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/time_traits.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:add time_traits< boost::posix_time::ptime >::add]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.add..add..time_traits< boost::posix_time::ptime >]
+Add a duration to a time.
+
+
+ static time_type add(
+ const time_type & t,
+ const duration_type & d);
+
+
+
+[endsect]
+
+
+
+[section:duration_type time_traits< boost::posix_time::ptime >::duration_type]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.duration_type..duration_type..time_traits< boost::posix_time::ptime >]
+The duration type.
+
+
+ typedef boost::posix_time::time_duration duration_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/time_traits.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:less_than time_traits< boost::posix_time::ptime >::less_than]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.less_than..less_than..time_traits< boost::posix_time::ptime >]
+Test whether one time is less than another.
+
+
+ static bool less_than(
+ const time_type & t1,
+ const time_type & t2);
+
+
+
+[endsect]
+
+
+
+[section:now time_traits< boost::posix_time::ptime >::now]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.now..now..time_traits< boost::posix_time::ptime >]
+Get the current time.
+
+
+ static time_type now();
+
+
+
+[endsect]
+
+
+
+[section:subtract time_traits< boost::posix_time::ptime >::subtract]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.subtract..subtract..time_traits< boost::posix_time::ptime >]
+Subtract one time from another.
+
+
+ static duration_type subtract(
+ const time_type & t1,
+ const time_type & t2);
+
+
+
+[endsect]
+
+
+
+[section:time_type time_traits< boost::posix_time::ptime >::time_type]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.time_type..time_type..time_traits< boost::posix_time::ptime >]
+The time type.
+
+
+ typedef boost::posix_time::ptime time_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/time_traits.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:to_posix_duration time_traits< boost::posix_time::ptime >::to_posix_duration]
+
+[indexterm2 asio.indexterm.time_traits_lt__ptime__gt_.to_posix_duration..to_posix_duration..time_traits< boost::posix_time::ptime >]
+Convert to POSIX duration type.
+
+
+ static boost::posix_time::time_duration to_posix_duration(
+ const duration_type & d);
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+
+[section:transfer_all transfer_all]
+
+[indexterm1 asio.indexterm.transfer_all..transfer_all]
+Return a completion condition function object that indicates that a read or write operation should continue until all of the data has been transferred, or until an error occurs.
+
+
+ unspecified transfer_all();
+
+
+This function is used to create an object, of unspecified type, that meets CompletionCondition requirements.
+
+
+[heading Example]
+
+Reading until a buffer is full:
+
+ boost::array<char, 128> buf;
+ asio::error_code ec;
+ std::size_t n = asio::read(
+ sock, asio::buffer(buf),
+ asio::transfer_all(), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ // n == 128
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/completion_condition.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:transfer_at_least transfer_at_least]
+
+[indexterm1 asio.indexterm.transfer_at_least..transfer_at_least]
+Return a completion condition function object that indicates that a read or write operation should continue until a minimum number of bytes has been transferred, or until an error occurs.
+
+
+ unspecified transfer_at_least(
+ std::size_t minimum);
+
+
+This function is used to create an object, of unspecified type, that meets CompletionCondition requirements.
+
+
+[heading Example]
+
+Reading until a buffer is full or contains at least 64 bytes:
+
+ boost::array<char, 128> buf;
+ asio::error_code ec;
+ std::size_t n = asio::read(
+ sock, asio::buffer(buf),
+ asio::transfer_at_least(64), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ // n >= 64 && n <= 128
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/completion_condition.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:transfer_exactly transfer_exactly]
+
+[indexterm1 asio.indexterm.transfer_exactly..transfer_exactly]
+Return a completion condition function object that indicates that a read or write operation should continue until an exact number of bytes has been transferred, or until an error occurs.
+
+
+ unspecified transfer_exactly(
+ std::size_t size);
+
+
+This function is used to create an object, of unspecified type, that meets CompletionCondition requirements.
+
+
+[heading Example]
+
+Reading until a buffer is full or contains exactly 64 bytes:
+
+ boost::array<char, 128> buf;
+ asio::error_code ec;
+ std::size_t n = asio::read(
+ sock, asio::buffer(buf),
+ asio::transfer_exactly(64), ec);
+ if (ec)
+ {
+ // An error occurred.
+ }
+ else
+ {
+ // n == 64
+ }
+
+
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/completion_condition.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:use_future use_future]
+
+[indexterm1 asio.indexterm.use_future..use_future]
+A special value, similar to std::nothrow.
+
+
+ constexpr use_future_t use_future;
+
+
+See the documentation for [link asio.reference.use_future_t `use_future_t`] for a usage example.
+
+[heading Requirements]
+
+['Header: ][^asio/use_future.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+[section:use_future_t use_future_t]
+
+
+Class used to specify that an asynchronous operation should return a future.
+
+
+ template<
+ typename Allocator = std::allocator<void>>
+ class use_future_t
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.use_future_t.allocator_type [*allocator_type]]]
+ [The allocator type. The allocator is used when constructing the std::promise object for a given asynchronous operation. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.use_future_t.get_allocator [*get_allocator]]]
+ [Obtain allocator. ]
+ ]
+
+ [
+ [[link asio.reference.use_future_t.operator_lp__rp_ [*operator()]]]
+ [Wrap a function object in a packaged task. ]
+ ]
+
+ [
+ [[link asio.reference.use_future_t.operator_lb__rb_ [*operator\[\]]]]
+ [(Deprecated: Use rebind().) Specify an alternate allocator. ]
+ ]
+
+ [
+ [[link asio.reference.use_future_t.rebind [*rebind]]]
+ [Specify an alternate allocator. ]
+ ]
+
+ [
+ [[link asio.reference.use_future_t.use_future_t [*use_future_t]]]
+ [Construct using default-constructed allocator.
+
+ Construct using specified allocator. ]
+ ]
+
+]
+
+The [link asio.reference.use_future_t `use_future_t`] class is used to indicate that an asynchronous operation should return a std::future object. A [link asio.reference.use_future_t `use_future_t`] object may be passed as a handler to an asynchronous operation, typically using the special value `asio::use_future`. For example:
+
+
+
+ std::future<std::size_t> my_future
+ = my_socket.async_read_some(my_buffer, asio::use_future);
+
+
+
+
+The initiating function (async\_read\_some in the above example) returns a future that will receive the result of the operation. If the operation completes with an [link asio.reference.error_code `error_code`] indicating failure, it is converted into a [link asio.reference.system_error `system_error`] and passed back to the caller via the future.
+
+[heading Requirements]
+
+['Header: ][^asio/use_future.hpp]
+
+['Convenience header: ]None
+
+
+[section:allocator_type use_future_t::allocator_type]
+
+[indexterm2 asio.indexterm.use_future_t.allocator_type..allocator_type..use_future_t]
+The allocator type. The allocator is used when constructing the `std::promise` object for a given asynchronous operation.
+
+
+ typedef Allocator allocator_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/use_future.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+
+[section:get_allocator use_future_t::get_allocator]
+
+[indexterm2 asio.indexterm.use_future_t.get_allocator..get_allocator..use_future_t]
+Obtain allocator.
+
+
+ allocator_type get_allocator() const;
+
+
+
+[endsect]
+
+
+
+[section:operator_lp__rp_ use_future_t::operator()]
+
+[indexterm2 asio.indexterm.use_future_t.operator_lp__rp_..operator()..use_future_t]
+Wrap a function object in a packaged task.
+
+
+ template<
+ typename Function>
+ unspecified operator()(
+ Function && f) const;
+
+
+The `package` function is used to adapt a function object as a packaged task. When this adapter is passed as a completion token to an asynchronous operation, the result of the function object is retuned via a std::future.
+
+
+[heading Example]
+
+
+
+
+
+ std::future<std::size_t> fut =
+ my_socket.async_read_some(buffer,
+ use_future([](asio::error_code ec, std::size_t n)
+ {
+ return ec ? 0 : n;
+ }));
+ ...
+ std::size_t n = fut.get();
+
+
+
+
+
+[endsect]
+
+
+
+[section:operator_lb__rb_ use_future_t::operator\[\]]
+
+[indexterm2 asio.indexterm.use_future_t.operator_lb__rb_..operator\[\]..use_future_t]
+(Deprecated: Use `rebind()`.) Specify an alternate allocator.
+
+
+ template<
+ typename OtherAllocator>
+ use_future_t< OtherAllocator > operator[](
+ const OtherAllocator & allocator) const;
+
+
+
+[endsect]
+
+
+
+[section:rebind use_future_t::rebind]
+
+[indexterm2 asio.indexterm.use_future_t.rebind..rebind..use_future_t]
+Specify an alternate allocator.
+
+
+ template<
+ typename OtherAllocator>
+ use_future_t< OtherAllocator > rebind(
+ const OtherAllocator & allocator) const;
+
+
+
+[endsect]
+
+
+[section:use_future_t use_future_t::use_future_t]
+
+[indexterm2 asio.indexterm.use_future_t.use_future_t..use_future_t..use_future_t]
+Construct using default-constructed allocator.
+
+
+ constexpr ``[link asio.reference.use_future_t.use_future_t.overload1 use_future_t]``();
+ `` [''''&raquo;''' [link asio.reference.use_future_t.use_future_t.overload1 more...]]``
+
+
+Construct using specified allocator.
+
+
+ explicit ``[link asio.reference.use_future_t.use_future_t.overload2 use_future_t]``(
+ const Allocator & allocator);
+ `` [''''&raquo;''' [link asio.reference.use_future_t.use_future_t.overload2 more...]]``
+
+
+[section:overload1 use_future_t::use_future_t (1 of 2 overloads)]
+
+
+Construct using default-constructed allocator.
+
+
+ constexpr use_future_t();
+
+
+
+[endsect]
+
+
+
+[section:overload2 use_future_t::use_future_t (2 of 2 overloads)]
+
+
+Construct using specified allocator.
+
+
+ use_future_t(
+ const Allocator & allocator);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:use_service use_service]
+
+[indexterm1 asio.indexterm.use_service..use_service]
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ Service & ``[link asio.reference.use_service.overload1 use_service]``(
+ execution_context & e);
+ `` [''''&raquo;''' [link asio.reference.use_service.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ Service & ``[link asio.reference.use_service.overload2 use_service]``(
+ io_context & ioc);
+ `` [''''&raquo;''' [link asio.reference.use_service.overload2 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/impl/execution_context.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 use_service (1 of 2 overloads)]
+
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ Service & use_service(
+ execution_context & e);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.execution_context `execution_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[e][The [link asio.reference.execution_context `execution_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 use_service (2 of 2 overloads)]
+
+
+
+ template<
+ typename ``[link asio.reference.Service Service]``>
+ Service & use_service(
+ io_context & ioc);
+
+
+This function is used to locate a service object that corresponds to the given service type. If there is no existing implementation of the service, then the [link asio.reference.io_context `io_context`] will create a new instance of the service.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ioc][The [link asio.reference.io_context `io_context`] object that owns the service.]]
+
+]
+
+
+[heading Return Value]
+
+The service interface implementing the specified service type. Ownership of the service interface is not transferred to the caller.
+
+
+[heading Remarks]
+
+This overload is preserved for backwards compatibility with services that inherit from [link asio.reference.io_context__service `io_context::service`].
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:uses_executor uses_executor]
+
+
+The [link asio.reference.uses_executor `uses_executor`] trait detects whether a type T has an associated executor that is convertible from type Executor.
+
+
+ template<
+ typename T,
+ typename ``[link asio.reference.Executor1 Executor]``>
+ struct uses_executor
+
+
+Meets the BinaryTypeTrait requirements. The Asio library provides a definition that is derived from false\_type. A program may specialize this template to derive from true\_type for a user-defined type T that can be constructed with an executor, where the first argument of a constructor has type [link asio.reference.executor_arg_t `executor_arg_t`] and the second argument is convertible from type Executor.
+
+[heading Requirements]
+
+['Header: ][^asio/uses_executor.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+[section:wait_traits wait_traits]
+
+
+Wait traits suitable for use with the [link asio.reference.basic_waitable_timer `basic_waitable_timer`] class template.
+
+
+ template<
+ typename Clock>
+ struct wait_traits
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.wait_traits.to_wait_duration [*to_wait_duration]]]
+ [Convert a clock duration into a duration used for waiting. ]
+ ]
+
+]
+
+[heading Requirements]
+
+['Header: ][^asio/wait_traits.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:to_wait_duration wait_traits::to_wait_duration]
+
+[indexterm2 asio.indexterm.wait_traits.to_wait_duration..to_wait_duration..wait_traits]
+Convert a clock duration into a duration used for waiting.
+
+
+ static Clock::duration ``[link asio.reference.wait_traits.to_wait_duration.overload1 to_wait_duration]``(
+ const typename Clock::duration & d);
+ `` [''''&raquo;''' [link asio.reference.wait_traits.to_wait_duration.overload1 more...]]``
+
+ static Clock::duration ``[link asio.reference.wait_traits.to_wait_duration.overload2 to_wait_duration]``(
+ const typename Clock::time_point & t);
+ `` [''''&raquo;''' [link asio.reference.wait_traits.to_wait_duration.overload2 more...]]``
+
+
+[section:overload1 wait_traits::to_wait_duration (1 of 2 overloads)]
+
+
+Convert a clock duration into a duration used for waiting.
+
+
+ static Clock::duration to_wait_duration(
+ const typename Clock::duration & d);
+
+
+
+[heading Return Value]
+
+`d`.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 wait_traits::to_wait_duration (2 of 2 overloads)]
+
+
+Convert a clock duration into a duration used for waiting.
+
+
+ static Clock::duration to_wait_duration(
+ const typename Clock::time_point & t);
+
+
+
+[heading Return Value]
+
+`d`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:windows__object_handle windows::object_handle]
+
+
+Provides object-oriented handle functionality.
+
+
+ class object_handle
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__object_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__object_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An object_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__object_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__object_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the object handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.object_handle [*object_handle]]]
+ [Construct an object_handle without opening it.
+
+ Construct an object_handle on an existing native handle.
+
+ Move-construct an object_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.operator_eq_ [*operator=]]]
+ [Move-assign an object_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.wait [*wait]]]
+ [Perform a blocking wait on the object handle. ]
+ ]
+
+]
+
+The [link asio.reference.windows__object_handle `windows::object_handle`] class provides asynchronous and blocking object-oriented handle functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/object_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign windows::object_handle::assign]
+
+[indexterm2 asio.indexterm.windows__object_handle.assign..assign..windows::object_handle]
+Assign an existing native handle to the handle.
+
+
+ void ``[link asio.reference.windows__object_handle.assign.overload1 assign]``(
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.assign.overload1 more...]]``
+
+ void ``[link asio.reference.windows__object_handle.assign.overload2 assign]``(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.assign.overload2 more...]]``
+
+
+[section:overload1 windows::object_handle::assign (1 of 2 overloads)]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle);
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::assign (2 of 2 overloads)]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_wait windows::object_handle::async_wait]
+
+[indexterm2 asio.indexterm.windows__object_handle.async_wait..async_wait..windows::object_handle]
+Start an asynchronous wait on the object handle.
+
+
+ template<
+ typename ``[link asio.reference.WaitHandler WaitHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_wait(
+ WaitHandler && handler);
+
+
+This function is be used to initiate an asynchronous wait against the object handle. It always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[handler][The handler to be called when the object handle is set to the signalled state. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error // Result of operation.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[section:cancel windows::object_handle::cancel]
+
+[indexterm2 asio.indexterm.windows__object_handle.cancel..cancel..windows::object_handle]
+Cancel all asynchronous operations associated with the handle.
+
+
+ void ``[link asio.reference.windows__object_handle.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.windows__object_handle.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.cancel.overload2 more...]]``
+
+
+[section:overload1 windows::object_handle::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close windows::object_handle::close]
+
+[indexterm2 asio.indexterm.windows__object_handle.close..close..windows::object_handle]
+Close the handle.
+
+
+ void ``[link asio.reference.windows__object_handle.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.close.overload1 more...]]``
+
+ void ``[link asio.reference.windows__object_handle.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.close.overload2 more...]]``
+
+
+[section:overload1 windows::object_handle::close (1 of 2 overloads)]
+
+
+Close the handle.
+
+
+ void close();
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::close (2 of 2 overloads)]
+
+
+Close the handle.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type windows::object_handle::executor_type]
+
+[indexterm2 asio.indexterm.windows__object_handle.executor_type..executor_type..windows::object_handle]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/object_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor windows::object_handle::get_executor]
+
+[indexterm2 asio.indexterm.windows__object_handle.get_executor..get_executor..windows::object_handle]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context windows::object_handle::get_io_context]
+
+[indexterm2 asio.indexterm.windows__object_handle.get_io_context..get_io_context..windows::object_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service windows::object_handle::get_io_service]
+
+[indexterm2 asio.indexterm.windows__object_handle.get_io_service..get_io_service..windows::object_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:is_open windows::object_handle::is_open]
+
+[indexterm2 asio.indexterm.windows__object_handle.is_open..is_open..windows::object_handle]
+Determine whether the handle is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer windows::object_handle::lowest_layer]
+
+[indexterm2 asio.indexterm.windows__object_handle.lowest_layer..lowest_layer..windows::object_handle]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.windows__object_handle.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.windows__object_handle.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 windows::object_handle::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__object_handle `windows::object_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__object_handle `windows::object_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type windows::object_handle::lowest_layer_type]
+
+[indexterm2 asio.indexterm.windows__object_handle.lowest_layer_type..lowest_layer_type..windows::object_handle]
+An [link asio.reference.windows__object_handle `windows::object_handle`] is always the lowest layer.
+
+
+ typedef object_handle lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__object_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__object_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An object_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__object_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__object_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.async_wait [*async_wait]]]
+ [Start an asynchronous wait on the object handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.object_handle [*object_handle]]]
+ [Construct an object_handle without opening it.
+
+ Construct an object_handle on an existing native handle.
+
+ Move-construct an object_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.operator_eq_ [*operator=]]]
+ [Move-assign an object_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__object_handle.wait [*wait]]]
+ [Perform a blocking wait on the object handle. ]
+ ]
+
+]
+
+The [link asio.reference.windows__object_handle `windows::object_handle`] class provides asynchronous and blocking object-oriented handle functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/object_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle windows::object_handle::native_handle]
+
+[indexterm2 asio.indexterm.windows__object_handle.native_handle..native_handle..windows::object_handle]
+Get the native handle representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the handle. This is intended to allow access to native handle functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type windows::object_handle::native_handle_type]
+
+[indexterm2 asio.indexterm.windows__object_handle.native_handle_type..native_handle_type..windows::object_handle]
+The native representation of a handle.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/object_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+[section:object_handle windows::object_handle::object_handle]
+
+[indexterm2 asio.indexterm.windows__object_handle.object_handle..object_handle..windows::object_handle]
+Construct an [link asio.reference.windows__object_handle `windows::object_handle`] without opening it.
+
+
+ explicit ``[link asio.reference.windows__object_handle.object_handle.overload1 object_handle]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.object_handle.overload1 more...]]``
+
+
+Construct an [link asio.reference.windows__object_handle `windows::object_handle`] on an existing native handle.
+
+
+ ``[link asio.reference.windows__object_handle.object_handle.overload2 object_handle]``(
+ asio::io_context & io_context,
+ const native_handle_type & native_handle);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.object_handle.overload2 more...]]``
+
+
+Move-construct an [link asio.reference.windows__object_handle `windows::object_handle`] from another.
+
+
+ ``[link asio.reference.windows__object_handle.object_handle.overload3 object_handle]``(
+ object_handle && other);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.object_handle.overload3 more...]]``
+
+
+[section:overload1 windows::object_handle::object_handle (1 of 3 overloads)]
+
+
+Construct an [link asio.reference.windows__object_handle `windows::object_handle`] without opening it.
+
+
+ object_handle(
+ asio::io_context & io_context);
+
+
+This constructor creates an object handle without opening it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the object handle will use to dispatch handlers for any asynchronous operations performed on the handle. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::object_handle (2 of 3 overloads)]
+
+
+Construct an [link asio.reference.windows__object_handle `windows::object_handle`] on an existing native handle.
+
+
+ object_handle(
+ asio::io_context & io_context,
+ const native_handle_type & native_handle);
+
+
+This constructor creates an object handle object to hold an existing native handle.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the object handle will use to dispatch handlers for any asynchronous operations performed on the handle.]]
+
+[[native_handle][The new underlying handle implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 windows::object_handle::object_handle (3 of 3 overloads)]
+
+
+Move-construct an [link asio.reference.windows__object_handle `windows::object_handle`] from another.
+
+
+ object_handle(
+ object_handle && other);
+
+
+This constructor moves an object handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__object_handle `windows::object_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `object_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:operator_eq_ windows::object_handle::operator=]
+
+[indexterm2 asio.indexterm.windows__object_handle.operator_eq_..operator=..windows::object_handle]
+Move-assign an [link asio.reference.windows__object_handle `windows::object_handle`] from another.
+
+
+ object_handle & operator=(
+ object_handle && other);
+
+
+This assignment operator moves an object handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__object_handle `windows::object_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `object_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[section:wait windows::object_handle::wait]
+
+[indexterm2 asio.indexterm.windows__object_handle.wait..wait..windows::object_handle]
+Perform a blocking wait on the object handle.
+
+
+ void ``[link asio.reference.windows__object_handle.wait.overload1 wait]``();
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.wait.overload1 more...]]``
+
+ void ``[link asio.reference.windows__object_handle.wait.overload2 wait]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__object_handle.wait.overload2 more...]]``
+
+
+[section:overload1 windows::object_handle::wait (1 of 2 overloads)]
+
+
+Perform a blocking wait on the object handle.
+
+
+ void wait();
+
+
+This function is used to wait for the object handle to be set to the signalled state. This function blocks and does not return until the object handle has been set to the signalled state.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::object_handle::wait (2 of 2 overloads)]
+
+
+Perform a blocking wait on the object handle.
+
+
+ void wait(
+ asio::error_code & ec);
+
+
+This function is used to wait for the object handle to be set to the signalled state. This function blocks and does not return until the object handle has been set to the signalled state.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:windows__overlapped_handle windows::overlapped_handle]
+
+
+Provides Windows handle functionality for objects that support overlapped I/O.
+
+
+ class overlapped_handle
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.operator_eq_ [*operator=]]]
+ [Move-assign an overlapped_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.overlapped_handle [*overlapped_handle]]]
+ [Construct an overlapped_handle without opening it.
+
+ Construct an overlapped_handle on an existing native handle.
+
+ Move-construct an overlapped_handle from another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle._overlapped_handle [*~overlapped_handle]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] class provides the ability to wrap a Windows handle. The underlying object referred to by the handle must support overlapped I/O.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/overlapped_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign windows::overlapped_handle::assign]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.assign..assign..windows::overlapped_handle]
+Assign an existing native handle to the handle.
+
+
+ void ``[link asio.reference.windows__overlapped_handle.assign.overload1 assign]``(
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.assign.overload1 more...]]``
+
+ void ``[link asio.reference.windows__overlapped_handle.assign.overload2 assign]``(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.assign.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_handle::assign (1 of 2 overloads)]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle);
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_handle::assign (2 of 2 overloads)]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:cancel windows::overlapped_handle::cancel]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.cancel..cancel..windows::overlapped_handle]
+Cancel all asynchronous operations associated with the handle.
+
+
+ void ``[link asio.reference.windows__overlapped_handle.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.windows__overlapped_handle.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.cancel.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_handle::cancel (1 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_handle::cancel (2 of 2 overloads)]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close windows::overlapped_handle::close]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.close..close..windows::overlapped_handle]
+Close the handle.
+
+
+ void ``[link asio.reference.windows__overlapped_handle.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.close.overload1 more...]]``
+
+ void ``[link asio.reference.windows__overlapped_handle.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.close.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_handle::close (1 of 2 overloads)]
+
+
+Close the handle.
+
+
+ void close();
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_handle::close (2 of 2 overloads)]
+
+
+Close the handle.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type windows::overlapped_handle::executor_type]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.executor_type..executor_type..windows::overlapped_handle]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/overlapped_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor windows::overlapped_handle::get_executor]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.get_executor..get_executor..windows::overlapped_handle]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context windows::overlapped_handle::get_io_context]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.get_io_context..get_io_context..windows::overlapped_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service windows::overlapped_handle::get_io_service]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.get_io_service..get_io_service..windows::overlapped_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:is_open windows::overlapped_handle::is_open]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.is_open..is_open..windows::overlapped_handle]
+Determine whether the handle is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer windows::overlapped_handle::lowest_layer]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.lowest_layer..lowest_layer..windows::overlapped_handle]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.windows__overlapped_handle.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.windows__overlapped_handle.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_handle::lowest_layer (1 of 2 overloads)]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_handle::lowest_layer (2 of 2 overloads)]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type windows::overlapped_handle::lowest_layer_type]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.lowest_layer_type..lowest_layer_type..windows::overlapped_handle]
+An [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] is always the lowest layer.
+
+
+ typedef overlapped_handle lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.operator_eq_ [*operator=]]]
+ [Move-assign an overlapped_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.overlapped_handle [*overlapped_handle]]]
+ [Construct an overlapped_handle without opening it.
+
+ Construct an overlapped_handle on an existing native handle.
+
+ Move-construct an overlapped_handle from another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle._overlapped_handle [*~overlapped_handle]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] class provides the ability to wrap a Windows handle. The underlying object referred to by the handle must support overlapped I/O.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/overlapped_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle windows::overlapped_handle::native_handle]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.native_handle..native_handle..windows::overlapped_handle]
+Get the native handle representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the handle. This is intended to allow access to native handle functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type windows::overlapped_handle::native_handle_type]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.native_handle_type..native_handle_type..windows::overlapped_handle]
+The native representation of a handle.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/overlapped_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ windows::overlapped_handle::operator=]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.operator_eq_..operator=..windows::overlapped_handle]
+Move-assign an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] from another.
+
+
+ overlapped_handle & operator=(
+ overlapped_handle && other);
+
+
+This assignment operator moves a handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `overlapped_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[section:overlapped_handle windows::overlapped_handle::overlapped_handle]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle.overlapped_handle..overlapped_handle..windows::overlapped_handle]
+Construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] without opening it.
+
+
+ explicit ``[link asio.reference.windows__overlapped_handle.overlapped_handle.overload1 overlapped_handle]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.overlapped_handle.overload1 more...]]``
+
+
+Construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] on an existing native handle.
+
+
+ ``[link asio.reference.windows__overlapped_handle.overlapped_handle.overload2 overlapped_handle]``(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.overlapped_handle.overload2 more...]]``
+
+
+Move-construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] from another.
+
+
+ ``[link asio.reference.windows__overlapped_handle.overlapped_handle.overload3 overlapped_handle]``(
+ overlapped_handle && other);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_handle.overlapped_handle.overload3 more...]]``
+
+
+[section:overload1 windows::overlapped_handle::overlapped_handle (1 of 3 overloads)]
+
+
+Construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] without opening it.
+
+
+ overlapped_handle(
+ asio::io_context & io_context);
+
+
+This constructor creates a handle without opening it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the handle will use to dispatch handlers for any asynchronous operations performed on the handle. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_handle::overlapped_handle (2 of 3 overloads)]
+
+
+Construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] on an existing native handle.
+
+
+ overlapped_handle(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+
+
+This constructor creates a handle object to hold an existing native handle.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the handle will use to dispatch handlers for any asynchronous operations performed on the handle.]]
+
+[[handle][A native handle.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 windows::overlapped_handle::overlapped_handle (3 of 3 overloads)]
+
+
+Move-construct an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] from another.
+
+
+ overlapped_handle(
+ overlapped_handle && other);
+
+
+This constructor moves a handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `overlapped_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_overlapped_handle windows::overlapped_handle::~overlapped_handle]
+
+[indexterm2 asio.indexterm.windows__overlapped_handle._overlapped_handle..~overlapped_handle..windows::overlapped_handle]
+Protected destructor to prevent deletion through this type.
+
+
+ ~overlapped_handle();
+
+
+This function destroys the handle, cancelling any outstanding asynchronous wait operations associated with the handle as if by calling `cancel`.
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:windows__overlapped_ptr windows::overlapped_ptr]
+
+
+Wraps a handler to create an OVERLAPPED object for use with overlapped I/O.
+
+
+ class overlapped_ptr :
+ noncopyable
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr.complete [*complete]]]
+ [Post completion notification for overlapped operation. Releases ownership. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr.get [*get]]]
+ [Get the contained OVERLAPPED object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr.overlapped_ptr [*overlapped_ptr]]]
+ [Construct an empty overlapped_ptr.
+
+ Construct an overlapped_ptr to contain the specified handler. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr.release [*release]]]
+ [Release ownership of the OVERLAPPED object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr.reset [*reset]]]
+ [Reset to empty.
+
+ Reset to contain the specified handler, freeing any current OVERLAPPED object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_ptr._overlapped_ptr [*~overlapped_ptr]]]
+ [Destructor automatically frees the OVERLAPPED object unless released. ]
+ ]
+
+]
+
+A special-purpose smart pointer used to wrap an application handler so that it can be passed as the LPOVERLAPPED argument to overlapped I/O functions.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/overlapped_ptr.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:complete windows::overlapped_ptr::complete]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr.complete..complete..windows::overlapped_ptr]
+Post completion notification for overlapped operation. Releases ownership.
+
+
+ void complete(
+ const asio::error_code & ec,
+ std::size_t bytes_transferred);
+
+
+
+[endsect]
+
+
+[section:get windows::overlapped_ptr::get]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr.get..get..windows::overlapped_ptr]
+Get the contained OVERLAPPED object.
+
+
+ OVERLAPPED * ``[link asio.reference.windows__overlapped_ptr.get.overload1 get]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.get.overload1 more...]]``
+
+ const OVERLAPPED * ``[link asio.reference.windows__overlapped_ptr.get.overload2 get]``() const;
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.get.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_ptr::get (1 of 2 overloads)]
+
+
+Get the contained OVERLAPPED object.
+
+
+ OVERLAPPED * get();
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_ptr::get (2 of 2 overloads)]
+
+
+Get the contained OVERLAPPED object.
+
+
+ const OVERLAPPED * get() const;
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:overlapped_ptr windows::overlapped_ptr::overlapped_ptr]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr.overlapped_ptr..overlapped_ptr..windows::overlapped_ptr]
+Construct an empty [link asio.reference.windows__overlapped_ptr `windows::overlapped_ptr`].
+
+
+ ``[link asio.reference.windows__overlapped_ptr.overlapped_ptr.overload1 overlapped_ptr]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.overlapped_ptr.overload1 more...]]``
+
+
+Construct an [link asio.reference.windows__overlapped_ptr `windows::overlapped_ptr`] to contain the specified handler.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ explicit ``[link asio.reference.windows__overlapped_ptr.overlapped_ptr.overload2 overlapped_ptr]``(
+ asio::io_context & io_context,
+ Handler && handler);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.overlapped_ptr.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_ptr::overlapped_ptr (1 of 2 overloads)]
+
+
+Construct an empty [link asio.reference.windows__overlapped_ptr `windows::overlapped_ptr`].
+
+
+ overlapped_ptr();
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_ptr::overlapped_ptr (2 of 2 overloads)]
+
+
+Construct an [link asio.reference.windows__overlapped_ptr `windows::overlapped_ptr`] to contain the specified handler.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ overlapped_ptr(
+ asio::io_context & io_context,
+ Handler && handler);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:release windows::overlapped_ptr::release]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr.release..release..windows::overlapped_ptr]
+Release ownership of the OVERLAPPED object.
+
+
+ OVERLAPPED * release();
+
+
+
+[endsect]
+
+
+[section:reset windows::overlapped_ptr::reset]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr.reset..reset..windows::overlapped_ptr]
+Reset to empty.
+
+
+ void ``[link asio.reference.windows__overlapped_ptr.reset.overload1 reset]``();
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.reset.overload1 more...]]``
+
+
+Reset to contain the specified handler, freeing any current OVERLAPPED object.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ void ``[link asio.reference.windows__overlapped_ptr.reset.overload2 reset]``(
+ asio::io_context & io_context,
+ Handler && handler);
+ `` [''''&raquo;''' [link asio.reference.windows__overlapped_ptr.reset.overload2 more...]]``
+
+
+[section:overload1 windows::overlapped_ptr::reset (1 of 2 overloads)]
+
+
+Reset to empty.
+
+
+ void reset();
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::overlapped_ptr::reset (2 of 2 overloads)]
+
+
+Reset to contain the specified handler, freeing any current OVERLAPPED object.
+
+
+ template<
+ typename ``[link asio.reference.Handler Handler]``>
+ void reset(
+ asio::io_context & io_context,
+ Handler && handler);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:_overlapped_ptr windows::overlapped_ptr::~overlapped_ptr]
+
+[indexterm2 asio.indexterm.windows__overlapped_ptr._overlapped_ptr..~overlapped_ptr..windows::overlapped_ptr]
+Destructor automatically frees the OVERLAPPED object unless released.
+
+
+ ~overlapped_ptr();
+
+
+
+[endsect]
+
+
+
+[endsect]
+
+[section:windows__random_access_handle windows::random_access_handle]
+
+
+Provides random-access handle functionality.
+
+
+ class random_access_handle :
+ public windows::overlapped_handle
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__random_access_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__random_access_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__random_access_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__random_access_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.async_read_some_at [*async_read_some_at]]]
+ [Start an asynchronous read at the specified offset. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.async_write_some_at [*async_write_some_at]]]
+ [Start an asynchronous write at the specified offset. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.operator_eq_ [*operator=]]]
+ [Move-assign a random_access_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.random_access_handle [*random_access_handle]]]
+ [Construct a random_access_handle without opening it.
+
+ Construct a random_access_handle on an existing native handle.
+
+ Move-construct a random_access_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.read_some_at [*read_some_at]]]
+ [Read some data from the handle at the specified offset. ]
+ ]
+
+ [
+ [[link asio.reference.windows__random_access_handle.write_some_at [*write_some_at]]]
+ [Write some data to the handle at the specified offset. ]
+ ]
+
+]
+
+The [link asio.reference.windows__random_access_handle `windows::random_access_handle`] class provides asynchronous and blocking random-access handle functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/random_access_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign windows::random_access_handle::assign]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.assign..assign..windows::random_access_handle]
+Assign an existing native handle to the handle.
+
+
+ void ``[link asio.reference.windows__random_access_handle.assign.overload1 assign]``(
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.assign.overload1 more...]]``
+
+ void ``[link asio.reference.windows__random_access_handle.assign.overload2 assign]``(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.assign.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::assign (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle);
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::assign (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_read_some_at windows::random_access_handle::async_read_some_at]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.async_read_some_at..async_read_some_at..windows::random_access_handle]
+Start an asynchronous read at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some_at(
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data from the random-access handle. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The read operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read_at `async_read_at`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.async_read_some_at(42, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some_at windows::random_access_handle::async_write_some_at]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.async_write_some_at..async_write_some_at..windows::random_access_handle]
+Start an asynchronous write at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some_at(
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write data to the random-access handle. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more data buffers to be written to the handle. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The write operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write_at `async_write_at`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.async_write_some_at(42, asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[section:cancel windows::random_access_handle::cancel]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.cancel..cancel..windows::random_access_handle]
+Cancel all asynchronous operations associated with the handle.
+
+
+ void ``[link asio.reference.windows__random_access_handle.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.windows__random_access_handle.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.cancel.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::cancel (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::cancel (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close windows::random_access_handle::close]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.close..close..windows::random_access_handle]
+Close the handle.
+
+
+ void ``[link asio.reference.windows__random_access_handle.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.close.overload1 more...]]``
+
+ void ``[link asio.reference.windows__random_access_handle.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.close.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::close (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Close the handle.
+
+
+ void close();
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::close (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Close the handle.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type windows::random_access_handle::executor_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.executor_type..executor_type..windows::random_access_handle]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/random_access_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor windows::random_access_handle::get_executor]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.get_executor..get_executor..windows::random_access_handle]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context windows::random_access_handle::get_io_context]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.get_io_context..get_io_context..windows::random_access_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service windows::random_access_handle::get_io_service]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.get_io_service..get_io_service..windows::random_access_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:is_open windows::random_access_handle::is_open]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.is_open..is_open..windows::random_access_handle]
+Determine whether the handle is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer windows::random_access_handle::lowest_layer]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.lowest_layer..lowest_layer..windows::random_access_handle]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.windows__random_access_handle.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.windows__random_access_handle.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type windows::random_access_handle::lowest_layer_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.lowest_layer_type..lowest_layer_type..windows::random_access_handle]
+An [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] is always the lowest layer.
+
+
+ typedef overlapped_handle lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.operator_eq_ [*operator=]]]
+ [Move-assign an overlapped_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.overlapped_handle [*overlapped_handle]]]
+ [Construct an overlapped_handle without opening it.
+
+ Construct an overlapped_handle on an existing native handle.
+
+ Move-construct an overlapped_handle from another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle._overlapped_handle [*~overlapped_handle]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] class provides the ability to wrap a Windows handle. The underlying object referred to by the handle must support overlapped I/O.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/random_access_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle windows::random_access_handle::native_handle]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.native_handle..native_handle..windows::random_access_handle]
+Get the native handle representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the handle. This is intended to allow access to native handle functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type windows::random_access_handle::native_handle_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.native_handle_type..native_handle_type..windows::random_access_handle]
+The native representation of a handle.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/random_access_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ windows::random_access_handle::operator=]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.operator_eq_..operator=..windows::random_access_handle]
+Move-assign a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] from another.
+
+
+ random_access_handle & operator=(
+ random_access_handle && other);
+
+
+This assignment operator moves a random-access handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__random_access_handle `windows::random_access_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `random_access_handle(io_context&)` constructor.
+
+
+
+
+[endsect]
+
+
+[section:random_access_handle windows::random_access_handle::random_access_handle]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.random_access_handle..random_access_handle..windows::random_access_handle]
+Construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] without opening it.
+
+
+ explicit ``[link asio.reference.windows__random_access_handle.random_access_handle.overload1 random_access_handle]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.random_access_handle.overload1 more...]]``
+
+
+Construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] on an existing native handle.
+
+
+ ``[link asio.reference.windows__random_access_handle.random_access_handle.overload2 random_access_handle]``(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.random_access_handle.overload2 more...]]``
+
+
+Move-construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] from another.
+
+
+ ``[link asio.reference.windows__random_access_handle.random_access_handle.overload3 random_access_handle]``(
+ random_access_handle && other);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.random_access_handle.overload3 more...]]``
+
+
+[section:overload1 windows::random_access_handle::random_access_handle (1 of 3 overloads)]
+
+
+Construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] without opening it.
+
+
+ random_access_handle(
+ asio::io_context & io_context);
+
+
+This constructor creates a random-access handle without opening it. The handle needs to be opened before data can be written to or read from it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the random-access handle will use to dispatch handlers for any asynchronous operations performed on the handle. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::random_access_handle (2 of 3 overloads)]
+
+
+Construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] on an existing native handle.
+
+
+ random_access_handle(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+
+
+This constructor creates a random-access handle object to hold an existing native handle.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the random-access handle will use to dispatch handlers for any asynchronous operations performed on the handle.]]
+
+[[handle][The new underlying handle implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 windows::random_access_handle::random_access_handle (3 of 3 overloads)]
+
+
+Move-construct a [link asio.reference.windows__random_access_handle `windows::random_access_handle`] from another.
+
+
+ random_access_handle(
+ random_access_handle && other);
+
+
+This constructor moves a random-access handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__random_access_handle `windows::random_access_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `random_access_handle(io_context&)` constructor.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:read_some_at windows::random_access_handle::read_some_at]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.read_some_at..read_some_at..windows::random_access_handle]
+Read some data from the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__random_access_handle.read_some_at.overload1 read_some_at]``(
+ uint64_t offset,
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.read_some_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__random_access_handle.read_some_at.overload2 read_some_at]``(
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.read_some_at.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::read_some_at (1 of 2 overloads)]
+
+
+Read some data from the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some_at(
+ uint64_t offset,
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the random-access handle. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read_at `read_at`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.read_some_at(42, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::read_some_at (2 of 2 overloads)]
+
+
+Read some data from the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some_at(
+ uint64_t offset,
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the random-access handle. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be read.]]
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read_at `read_at`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some_at windows::random_access_handle::write_some_at]
+
+[indexterm2 asio.indexterm.windows__random_access_handle.write_some_at..write_some_at..windows::random_access_handle]
+Write some data to the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__random_access_handle.write_some_at.overload1 write_some_at]``(
+ uint64_t offset,
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.write_some_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__random_access_handle.write_some_at.overload2 write_some_at]``(
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__random_access_handle.write_some_at.overload2 more...]]``
+
+
+[section:overload1 windows::random_access_handle::write_some_at (1 of 2 overloads)]
+
+
+Write some data to the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some_at(
+ uint64_t offset,
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data to the random-access handle. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more data buffers to be written to the handle.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some\_at operation may not write all of the data. Consider using the [link asio.reference.write_at `write_at`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.write_some_at(42, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::random_access_handle::write_some_at (2 of 2 overloads)]
+
+
+Write some data to the handle at the specified offset.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some_at(
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data to the random-access handle. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more data buffers to be written to the handle.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write_at `write_at`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:windows__stream_handle windows::stream_handle]
+
+
+Provides stream-oriented handle functionality.
+
+
+ class stream_handle :
+ public windows::overlapped_handle
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__stream_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__stream_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__stream_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__stream_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.async_read_some [*async_read_some]]]
+ [Start an asynchronous read. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.async_write_some [*async_write_some]]]
+ [Start an asynchronous write. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.operator_eq_ [*operator=]]]
+ [Move-assign a stream_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.read_some [*read_some]]]
+ [Read some data from the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.stream_handle [*stream_handle]]]
+ [Construct a stream_handle without opening it.
+
+ Construct a stream_handle on an existing native handle.
+
+ Move-construct a stream_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__stream_handle.write_some [*write_some]]]
+ [Write some data to the handle. ]
+ ]
+
+]
+
+The [link asio.reference.windows__stream_handle `windows::stream_handle`] class provides asynchronous and blocking stream-oriented handle functionality.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/stream_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+[section:assign windows::stream_handle::assign]
+
+[indexterm2 asio.indexterm.windows__stream_handle.assign..assign..windows::stream_handle]
+Assign an existing native handle to the handle.
+
+
+ void ``[link asio.reference.windows__stream_handle.assign.overload1 assign]``(
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.assign.overload1 more...]]``
+
+ void ``[link asio.reference.windows__stream_handle.assign.overload2 assign]``(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.assign.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::assign (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle);
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::assign (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Assign an existing native handle to the handle.
+
+
+ void assign(
+ const native_handle_type & handle,
+ asio::error_code & ec);
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:async_read_some windows::stream_handle::async_read_some]
+
+[indexterm2 asio.indexterm.windows__stream_handle.async_read_some..async_read_some..windows::stream_handle]
+Start an asynchronous read.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+ typename ``[link asio.reference.ReadHandler ReadHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_read_some(
+ const MutableBufferSequence & buffers,
+ ReadHandler && handler);
+
+
+This function is used to asynchronously read data from the stream handle. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.]]
+
+[[handler][The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The read operation may not read all of the requested number of bytes. Consider using the [link asio.reference.async_read `async_read`] function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.async_read_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:async_write_some windows::stream_handle::async_write_some]
+
+[indexterm2 asio.indexterm.windows__stream_handle.async_write_some..async_write_some..windows::stream_handle]
+Start an asynchronous write.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.WriteHandler WriteHandler]``>
+ ``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]`` async_write_some(
+ const ConstBufferSequence & buffers,
+ WriteHandler && handler);
+
+
+This function is used to asynchronously write data to the stream handle. The function call always returns immediately.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the handle. 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.]]
+
+[[handler][The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:
+``
+ void handler(
+ const asio::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ );
+``
+Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using `asio::io_context::post()`.]]
+
+]
+
+
+[heading Remarks]
+
+The write operation may not transmit all of the data to the peer. Consider using the [link asio.reference.async_write `async_write`] function if you need to ensure that all data is written before the asynchronous operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.async_write_some(asio::buffer(data, size), handler);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+[section:cancel windows::stream_handle::cancel]
+
+[indexterm2 asio.indexterm.windows__stream_handle.cancel..cancel..windows::stream_handle]
+Cancel all asynchronous operations associated with the handle.
+
+
+ void ``[link asio.reference.windows__stream_handle.cancel.overload1 cancel]``();
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.cancel.overload1 more...]]``
+
+ void ``[link asio.reference.windows__stream_handle.cancel.overload2 cancel]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.cancel.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::cancel (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel();
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::cancel (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Cancel all asynchronous operations associated with the handle.
+
+
+ void cancel(
+ asio::error_code & ec);
+
+
+This function causes all outstanding asynchronous read or write operations to finish immediately, and the handlers for cancelled operations will be passed the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:close windows::stream_handle::close]
+
+[indexterm2 asio.indexterm.windows__stream_handle.close..close..windows::stream_handle]
+Close the handle.
+
+
+ void ``[link asio.reference.windows__stream_handle.close.overload1 close]``();
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.close.overload1 more...]]``
+
+ void ``[link asio.reference.windows__stream_handle.close.overload2 close]``(
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.close.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::close (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Close the handle.
+
+
+ void close();
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::close (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Close the handle.
+
+
+ void close(
+ asio::error_code & ec);
+
+
+This function is used to close the handle. Any asynchronous read or write operations will be cancelled immediately, and will complete with the `asio::error::operation_aborted` error.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[ec][Set to indicate what error occurred, if any. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:executor_type windows::stream_handle::executor_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.executor_type..executor_type..windows::stream_handle]
+The type of the executor associated with the object.
+
+
+ typedef io_context::executor_type executor_type;
+
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.context [*context]]]
+ [Obtain the underlying execution context. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.defer [*defer]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.dispatch [*dispatch]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_finished [*on_work_finished]]]
+ [Inform the io_context that some work is no longer outstanding. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.on_work_started [*on_work_started]]]
+ [Inform the io_context that it has some outstanding work to do. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.post [*post]]]
+ [Request the io_context to invoke the given function object. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.running_in_this_thread [*running_in_this_thread]]]
+ [Determine whether the io_context is running in the current thread. ]
+ ]
+
+]
+
+[heading Friends]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_not__eq_ [*operator!=]]]
+ [Compare two executors for inequality. ]
+ ]
+
+ [
+ [[link asio.reference.io_context__executor_type.operator_eq__eq_ [*operator==]]]
+ [Compare two executors for equality. ]
+ ]
+
+]
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/stream_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:get_executor windows::stream_handle::get_executor]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.get_executor..get_executor..windows::stream_handle]
+Get the executor associated with the object.
+
+
+ executor_type get_executor();
+
+
+
+[endsect]
+
+
+
+[section:get_io_context windows::stream_handle::get_io_context]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.get_io_context..get_io_context..windows::stream_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_context();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:get_io_service windows::stream_handle::get_io_service]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.get_io_service..get_io_service..windows::stream_handle]
+(Deprecated: Use `get_executor()`.) Get the [link asio.reference.io_context `io_context`] associated with the object.
+
+
+ asio::io_context & get_io_service();
+
+
+This function may be used to obtain the [link asio.reference.io_context `io_context`] object that the I/O object uses to dispatch handlers for asynchronous operations.
+
+
+[heading Return Value]
+
+A reference to the [link asio.reference.io_context `io_context`] object that the I/O object will use to dispatch handlers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:is_open windows::stream_handle::is_open]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.is_open..is_open..windows::stream_handle]
+Determine whether the handle is open.
+
+
+ bool is_open() const;
+
+
+
+[endsect]
+
+
+[section:lowest_layer windows::stream_handle::lowest_layer]
+
+[indexterm2 asio.indexterm.windows__stream_handle.lowest_layer..lowest_layer..windows::stream_handle]
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & ``[link asio.reference.windows__stream_handle.lowest_layer.overload1 lowest_layer]``();
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.lowest_layer.overload1 more...]]``
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & ``[link asio.reference.windows__stream_handle.lowest_layer.overload2 lowest_layer]``() const;
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.lowest_layer.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::lowest_layer (1 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Get a reference to the lowest layer.
+
+
+ lowest_layer_type & lowest_layer();
+
+
+This function returns a reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::lowest_layer (2 of 2 overloads)]
+
+
+['Inherited from windows::overlapped_handle.]
+
+
+Get a const reference to the lowest layer.
+
+
+ const lowest_layer_type & lowest_layer() const;
+
+
+This function returns a const reference to the lowest layer in a stack of layers. Since an [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] cannot contain any further layers, it simply returns a reference to itself.
+
+
+[heading Return Value]
+
+A const reference to the lowest layer in the stack of layers. Ownership is not transferred to the caller.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:lowest_layer_type windows::stream_handle::lowest_layer_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.lowest_layer_type..lowest_layer_type..windows::stream_handle]
+An [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] is always the lowest layer.
+
+
+ typedef overlapped_handle lowest_layer_type;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.executor_type [*executor_type]]]
+ [The type of the executor associated with the object. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.lowest_layer_type [*lowest_layer_type]]]
+ [An overlapped_handle is always the lowest layer. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.windows__overlapped_handle.native_handle_type [*native_handle_type]]]
+ [The native representation of a handle. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.assign [*assign]]]
+ [Assign an existing native handle to the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.cancel [*cancel]]]
+ [Cancel all asynchronous operations associated with the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.close [*close]]]
+ [Close the handle. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_executor [*get_executor]]]
+ [Get the executor associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_context [*get_io_context]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.get_io_service [*get_io_service]]]
+ [(Deprecated: Use get_executor().) Get the io_context associated with the object. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.is_open [*is_open]]]
+ [Determine whether the handle is open. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.lowest_layer [*lowest_layer]]]
+ [Get a reference to the lowest layer.
+
+ Get a const reference to the lowest layer. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.native_handle [*native_handle]]]
+ [Get the native handle representation. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.operator_eq_ [*operator=]]]
+ [Move-assign an overlapped_handle from another. ]
+ ]
+
+ [
+ [[link asio.reference.windows__overlapped_handle.overlapped_handle [*overlapped_handle]]]
+ [Construct an overlapped_handle without opening it.
+
+ Construct an overlapped_handle on an existing native handle.
+
+ Move-construct an overlapped_handle from another. ]
+ ]
+
+]
+
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.windows__overlapped_handle._overlapped_handle [*~overlapped_handle]]]
+ [Protected destructor to prevent deletion through this type. ]
+ ]
+
+]
+
+The [link asio.reference.windows__overlapped_handle `windows::overlapped_handle`] class provides the ability to wrap a Windows handle. The underlying object referred to by the handle must support overlapped I/O.
+
+
+[heading Thread Safety]
+
+['Distinct] ['objects:] Safe.
+
+['Shared] ['objects:] Unsafe.
+
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/stream_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:native_handle windows::stream_handle::native_handle]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.native_handle..native_handle..windows::stream_handle]
+Get the native handle representation.
+
+
+ native_handle_type native_handle();
+
+
+This function may be used to obtain the underlying representation of the handle. This is intended to allow access to native handle functionality that is not otherwise provided.
+
+
+[endsect]
+
+
+
+[section:native_handle_type windows::stream_handle::native_handle_type]
+
+
+['Inherited from windows::overlapped_handle.]
+
+[indexterm2 asio.indexterm.windows__stream_handle.native_handle_type..native_handle_type..windows::stream_handle]
+The native representation of a handle.
+
+
+ typedef implementation_defined native_handle_type;
+
+
+
+[heading Requirements]
+
+['Header: ][^asio/windows/stream_handle.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_eq_ windows::stream_handle::operator=]
+
+[indexterm2 asio.indexterm.windows__stream_handle.operator_eq_..operator=..windows::stream_handle]
+Move-assign a [link asio.reference.windows__stream_handle `windows::stream_handle`] from another.
+
+
+ stream_handle & operator=(
+ stream_handle && other);
+
+
+This assignment operator moves a stream handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__stream_handle `windows::stream_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `stream_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[section:read_some windows::stream_handle::read_some]
+
+[indexterm2 asio.indexterm.windows__stream_handle.read_some..read_some..windows::stream_handle]
+Read some data from the handle.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__stream_handle.read_some.overload1 read_some]``(
+ const MutableBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.read_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__stream_handle.read_some.overload2 read_some]``(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.read_some.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::read_some (1 of 2 overloads)]
+
+
+Read some data from the handle.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers);
+
+
+This function is used to read data from the stream handle. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+[heading Example]
+
+To read into a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.read_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::read_some (2 of 2 overloads)]
+
+
+Read some data from the handle.
+
+
+ template<
+ typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
+ std::size_t read_some(
+ const MutableBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to read data from the stream handle. The function call will block until one or more bytes of data has been read successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more buffers into which the data will be read.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes read. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The read\_some operation may not read all of the requested number of bytes. Consider using the [link asio.reference.read `read`] function if you need to ensure that the requested amount of data is read before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:stream_handle windows::stream_handle::stream_handle]
+
+[indexterm2 asio.indexterm.windows__stream_handle.stream_handle..stream_handle..windows::stream_handle]
+Construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] without opening it.
+
+
+ explicit ``[link asio.reference.windows__stream_handle.stream_handle.overload1 stream_handle]``(
+ asio::io_context & io_context);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.stream_handle.overload1 more...]]``
+
+
+Construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] on an existing native handle.
+
+
+ ``[link asio.reference.windows__stream_handle.stream_handle.overload2 stream_handle]``(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.stream_handle.overload2 more...]]``
+
+
+Move-construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] from another.
+
+
+ ``[link asio.reference.windows__stream_handle.stream_handle.overload3 stream_handle]``(
+ stream_handle && other);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.stream_handle.overload3 more...]]``
+
+
+[section:overload1 windows::stream_handle::stream_handle (1 of 3 overloads)]
+
+
+Construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] without opening it.
+
+
+ stream_handle(
+ asio::io_context & io_context);
+
+
+This constructor creates a stream handle without opening it. The handle needs to be opened and then connected or accepted before data can be sent or received on it.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream handle will use to dispatch handlers for any asynchronous operations performed on the handle. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::stream_handle (2 of 3 overloads)]
+
+
+Construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] on an existing native handle.
+
+
+ stream_handle(
+ asio::io_context & io_context,
+ const native_handle_type & handle);
+
+
+This constructor creates a stream handle object to hold an existing native handle.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[io_context][The [link asio.reference.io_context `io_context`] object that the stream handle will use to dispatch handlers for any asynchronous operations performed on the handle.]]
+
+[[handle][The new underlying handle implementation.]]
+
+]
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 windows::stream_handle::stream_handle (3 of 3 overloads)]
+
+
+Move-construct a [link asio.reference.windows__stream_handle `windows::stream_handle`] from another.
+
+
+ stream_handle(
+ stream_handle && other);
+
+
+This constructor moves a stream handle from one object to another.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[other][The other [link asio.reference.windows__stream_handle `windows::stream_handle`] object from which the move will occur.]]
+
+]
+
+
+[heading Remarks]
+
+Following the move, the moved-from object is in the same state as if constructed using the `stream_handle(io_context&) constructor`.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_some windows::stream_handle::write_some]
+
+[indexterm2 asio.indexterm.windows__stream_handle.write_some..write_some..windows::stream_handle]
+Write some data to the handle.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__stream_handle.write_some.overload1 write_some]``(
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.write_some.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.windows__stream_handle.write_some.overload2 write_some]``(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.windows__stream_handle.write_some.overload2 more...]]``
+
+
+[section:overload1 windows::stream_handle::write_some (1 of 2 overloads)]
+
+
+Write some data to the handle.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write data to the stream handle. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the handle.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. An error code of `asio::error::eof` indicates that the connection was closed by the peer.]]
+
+]
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ handle.write_some(asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 windows::stream_handle::write_some (2 of 2 overloads)]
+
+
+Write some data to the handle.
+
+
+ template<
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_some(
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write data to the stream handle. The function call will block until one or more bytes of the data has been written successfully, or until an error occurs.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[buffers][One or more data buffers to be written to the handle.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. Returns 0 if an error occurred.
+
+
+[heading Remarks]
+
+The write\_some operation may not transmit all of the data to the peer. Consider using the [link asio.reference.write `write`] function if you need to ensure that all data is written before the blocking operation completes.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write write]
+
+[indexterm1 asio.indexterm.write..write]
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.write.overload1 write]``(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.write.overload2 write]``(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload3 write]``(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload4 write]``(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.write.overload5 write]``(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t ``[link asio.reference.write.overload6 write]``(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload7 write]``(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload8 write]``(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+ `` [''''&raquo;''' [link asio.reference.write.overload8 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.write.overload9 write]``(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b);
+ `` [''''&raquo;''' [link asio.reference.write.overload9 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.write.overload10 write]``(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write.overload10 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload11 write]``(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.write.overload11 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write.overload12 write]``(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write.overload12 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/write.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 write (1 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the stream.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write(s, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 write (2 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the stream.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write(s, asio::buffer(data, size), ec);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 write (3 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the stream.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write(s, asio::buffer(data, size),
+ asio::transfer_at_least(32));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 write (4 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the stream.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 write (5 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. Successfully written data is automatically consumed from the buffers.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 write (6 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. Successfully written data is automatically consumed from the buffers.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 write (7 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. Successfully written data is automatically consumed from the buffers.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 write (8 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename ``[link asio.reference.DynamicBuffer DynamicBuffer]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ DynamicBuffer && buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec,
+ typename enable_if< is_dynamic_buffer< DynamicBuffer >::value >::type * = 0);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied dynamic buffer sequence has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[buffers][The dynamic buffer sequence from which data will be written. Successfully written data is automatically consumed from the buffers.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload9 write (9 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator>
+ std::size_t write(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, b,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload10 write (10 of 12 overloads)]
+
+
+Write all of the supplied data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator>
+ std::size_t write(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write(
+ s, b,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload11 write (11 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload12 write (12 of 12 overloads)]
+
+
+Write a certain amount of data to a stream before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncWriteStream SyncWriteStream]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write(
+ SyncWriteStream & s,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the stream's write\_some function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[s][The stream to which the data is to be written. The type must support the SyncWriteStream concept.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the stream's write\_some function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+[section:write_at write_at]
+
+[indexterm1 asio.indexterm.write_at..write_at]
+Write a certain amount of data at a specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.write_at.overload1 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload1 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t ``[link asio.reference.write_at.overload2 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload2 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write_at.overload3 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload3 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write_at.overload4 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload4 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.write_at.overload5 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload5 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator>
+ std::size_t ``[link asio.reference.write_at.overload6 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload6 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write_at.overload7 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload7 more...]]``
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t ``[link asio.reference.write_at.overload8 write_at]``(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+ `` [''''&raquo;''' [link asio.reference.write_at.overload8 more...]]``
+
+[heading Requirements]
+
+['Header: ][^asio/write_at.hpp]
+
+['Convenience header: ][^asio.hpp]
+
+
+[section:overload1 write_at (1 of 8 overloads)]
+
+
+Write all of the supplied data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the device.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write_at(d, 42, asio::buffer(data, size));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write_at(
+ d, offset, buffers,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload2 write_at (2 of 8 overloads)]
+
+
+Write all of the supplied data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the device.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write_at(d, 42,
+ asio::buffer(data, size), ec);
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write_at(
+ d, offset, buffers,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload3 write_at (3 of 8 overloads)]
+
+
+Write a certain amount of data at a specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the device.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's write\_some\_at function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Example]
+
+To write a single data buffer use the [link asio.reference.buffer `buffer`] function as follows:
+
+ asio::write_at(d, 42, asio::buffer(data, size),
+ asio::transfer_at_least(32));
+
+
+See the [link asio.reference.buffer `buffer`] documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.
+
+
+
+
+[endsect]
+
+
+
+[section:overload4 write_at (4 of 8 overloads)]
+
+
+Write a certain amount of data at a specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ const ConstBufferSequence & buffers,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[buffers][One or more buffers containing the data to be written. The sum of the buffer sizes indicates the maximum number of bytes to write to the device.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's write\_some\_at function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+
+[section:overload5 write_at (5 of 8 overloads)]
+
+
+Write all of the supplied data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure.]]
+
+]
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write_at(
+ d, 42, b,
+ asio::transfer_all());
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload6 write_at (6 of 8 overloads)]
+
+
+Write all of the supplied data at the specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* An error occurred.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Remarks]
+
+This overload is equivalent to calling:
+
+ asio::write_at(
+ d, 42, b,
+ asio::transfer_all(), ec);
+
+
+
+
+
+
+
+[endsect]
+
+
+
+[section:overload7 write_at (7 of 8 overloads)]
+
+
+Write a certain amount of data at a specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's write\_some\_at function.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes transferred.
+
+
+[heading Exceptions]
+
+
+[variablelist
+
+[[asio::system_error][Thrown on failure. ]]
+
+]
+
+
+
+
+[endsect]
+
+
+
+[section:overload8 write_at (8 of 8 overloads)]
+
+
+Write a certain amount of data at a specified offset before returning.
+
+
+ template<
+ typename ``[link asio.reference.SyncRandomAccessWriteDevice SyncRandomAccessWriteDevice]``,
+ typename Allocator,
+ typename ``[link asio.reference.CompletionCondition CompletionCondition]``>
+ std::size_t write_at(
+ SyncRandomAccessWriteDevice & d,
+ uint64_t offset,
+ basic_streambuf< Allocator > & b,
+ CompletionCondition completion_condition,
+ asio::error_code & ec);
+
+
+This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
+
+
+* All of the data in the supplied [link asio.reference.basic_streambuf `basic_streambuf`] has been written.
+
+
+* The completion\_condition function object returns 0.
+
+This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
+
+
+[heading Parameters]
+
+
+[variablelist
+
+[[d][The device to which the data is to be written. The type must support the SyncRandomAccessWriteDevice concept.]]
+
+[[offset][The offset at which the data will be written.]]
+
+[[b][The [link asio.reference.basic_streambuf `basic_streambuf`] object from which data will be written.]]
+
+[[completion_condition][The function object to be called to determine whether the write operation is complete. The signature of the function object must be:
+``
+ std::size_t completion_condition(
+ // Result of latest write_some_at operation.
+ const asio::error_code& error,
+
+ // Number of bytes transferred so far.
+ std::size_t bytes_transferred
+ );
+``
+A return value of 0 indicates that the write operation is complete. A non-zero return value indicates the maximum number of bytes to be written on the next call to the device's write\_some\_at function.]]
+
+[[ec][Set to indicate what error occurred, if any.]]
+
+]
+
+
+[heading Return Value]
+
+The number of bytes written. If an error occurs, returns the total number of bytes successfully transferred prior to the error.
+
+
+
+
+[endsect]
+
+
+[endsect]
+
+
+[section:yield_context yield_context]
+
+[indexterm1 asio.indexterm.yield_context..yield_context]
+Context object that represents the currently executing coroutine.
+
+
+ typedef basic_yield_context< unspecified > yield_context;
+
+
+[heading Types]
+[table
+ [[Name][Description]]
+
+ [
+
+ [[link asio.reference.basic_yield_context.callee_type [*callee_type]]]
+ [The coroutine callee type, used by the implementation. ]
+
+ ]
+
+ [
+
+ [[link asio.reference.basic_yield_context.caller_type [*caller_type]]]
+ [The coroutine caller type, used by the implementation. ]
+
+ ]
+
+]
+
+[heading Member Functions]
+[table
+ [[Name][Description]]
+
+ [
+ [[link asio.reference.basic_yield_context.basic_yield_context [*basic_yield_context]]]
+ [Construct a yield context to represent the specified coroutine.
+
+ Construct a yield context from another yield context type. ]
+ ]
+
+ [
+ [[link asio.reference.basic_yield_context.operator_lb__rb_ [*operator\[\]]]]
+ [Return a yield context that sets the specified error_code. ]
+ ]
+
+]
+
+The [link asio.reference.basic_yield_context `basic_yield_context`] class is used to represent the currently executing stackful coroutine. A [link asio.reference.basic_yield_context `basic_yield_context`] may be passed as a handler to an asynchronous operation. For example:
+
+
+
+ template <typename Handler>
+ void my_coroutine(basic_yield_context<Handler> yield)
+ {
+ ...
+ std::size_t n = my_socket.async_read_some(buffer, yield);
+ ...
+ }
+
+
+
+
+The initiating function (async\_read\_some in the above example) suspends the current coroutine. The coroutine is resumed when the asynchronous operation completes, and the result of the operation is returned.
+
+
+[heading Requirements]
+
+['Header: ][^asio/spawn.hpp]
+
+['Convenience header: ]None
+
+
+[endsect]
+
+
+[endsect] \ No newline at end of file
diff --git a/3rdparty/asio/src/doc/reference.xsl b/3rdparty/asio/src/doc/reference.xsl
new file mode 100644
index 00000000000..e652cd9bd24
--- /dev/null
+++ b/3rdparty/asio/src/doc/reference.xsl
@@ -0,0 +1,1779 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ Copyright (c) 2003-2016 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)
+-->
+
+<xsl:output method="text"/>
+<xsl:strip-space elements="*"/>
+<xsl:preserve-space elements="para"/>
+
+
+<xsl:variable name="newline">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+
+<!--
+ Loop over all top-level documentation elements (i.e. classes, functions,
+ variables and typedefs at namespace scope). The elements are sorted by name.
+ Anything in a "detail" namespace or with "_handler" in the name is skipped.
+-->
+<xsl:template match="/doxygen">
+<xsl:text>[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:reference Reference]
+
+[xinclude quickref.xml]
+
+[include requirements/asynchronous_operations.qbk]
+[include requirements/read_write_operations.qbk]
+[include requirements/synchronous_socket_operations.qbk]
+[include requirements/asynchronous_socket_operations.qbk]
+[include requirements/AcceptableProtocol.qbk]
+[include requirements/AcceptHandler.qbk]
+[include requirements/AsyncRandomAccessReadDevice.qbk]
+[include requirements/AsyncRandomAccessWriteDevice.qbk]
+[include requirements/AsyncReadStream.qbk]
+[include requirements/AsyncWriteStream.qbk]
+[include requirements/BufferedHandshakeHandler.qbk]
+[include requirements/CompletionCondition.qbk]
+[include requirements/CompletionHandler.qbk]
+[include requirements/ConnectCondition.qbk]
+[include requirements/ConnectHandler.qbk]
+[include requirements/ConstBufferSequence.qbk]
+[include requirements/DynamicBuffer.qbk]
+[include requirements/Endpoint.qbk]
+[include requirements/EndpointSequence.qbk]
+[include requirements/ExecutionContext.qbk]
+[include requirements/Executor.qbk]
+[include requirements/GettableSerialPortOption.qbk]
+[include requirements/GettableSocketOption.qbk]
+[include requirements/Handler.qbk]
+[include requirements/HandshakeHandler.qbk]
+[include requirements/InternetProtocol.qbk]
+[include requirements/IoControlCommand.qbk]
+[include requirements/IoObjectService.qbk]
+[include requirements/IteratorConnectHandler.qbk]
+[include requirements/MoveAcceptHandler.qbk]
+[include requirements/MutableBufferSequence.qbk]
+[include requirements/ProtoAllocator.qbk]
+[include requirements/Protocol.qbk]
+[include requirements/RangeConnectHandler.qbk]
+[include requirements/ReadHandler.qbk]
+[include requirements/ResolveHandler.qbk]
+[include requirements/Service.qbk]
+[include requirements/SettableSerialPortOption.qbk]
+[include requirements/SettableSocketOption.qbk]
+[include requirements/ShutdownHandler.qbk]
+[include requirements/SignalHandler.qbk]
+[include requirements/SyncRandomAccessReadDevice.qbk]
+[include requirements/SyncRandomAccessWriteDevice.qbk]
+[include requirements/SyncReadStream.qbk]
+[include requirements/SyncWriteStream.qbk]
+[include requirements/TimeTraits.qbk]
+[include requirements/WaitHandler.qbk]
+[include requirements/WaitTraits.qbk]
+[include requirements/WriteHandler.qbk]
+
+</xsl:text>
+
+ <xsl:for-each select="
+ compounddef[@kind = 'class' or @kind = 'struct'] |
+ compounddef[@kind = 'namespace']/sectiondef[1]/memberdef">
+ <xsl:sort select="concat((. | ancestor::*)/compoundname, '::', name, ':x')"/>
+ <xsl:sort select="name"/>
+ <xsl:choose>
+ <xsl:when test="@kind='class' or @kind='struct'">
+ <xsl:if test="
+ contains(compoundname, 'asio::') and
+ not(contains(compoundname, '::detail')) and
+ not(contains(compoundname, '::service::key')) and
+ not(contains(compoundname, '_handler')) and
+ not(contains(compoundname, 'thread_function')) and
+ not(contains(compoundname, 'context_impl'))">
+ <xsl:call-template name="class"/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="
+ not(contains(ancestor::*/compoundname, '::detail')) and
+ not(contains(ancestor::*/compoundname, '::service::key')) and
+ not(contains(ancestor::*/compoundname, '_helper')) and
+ not(contains(name, '_helper')) and
+ not(contains(name, 'thread_function')) and
+ not(contains(name, 'io_context_impl'))">
+ <xsl:call-template name="namespace-memberdef"/>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <xsl:value-of select="$newline"/>
+ <xsl:text>[endsect]</xsl:text>
+
+</xsl:template>
+
+
+<!--========== Utilities ==========-->
+
+<xsl:template name="strip-asio-ns">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, 'boost::system::is_error_code_enum')">
+ <xsl:value-of select="$name"/>
+ </xsl:when>
+ <xsl:when test="contains($name, 'asio::')">
+ <xsl:value-of select="substring-after($name, 'asio::')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="strip-ns">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, 'boost::system::is_error_code_enum')">
+ <xsl:value-of select="$name"/>
+ </xsl:when>
+ <xsl:when test="contains($name, '::') and contains($name, '&lt;')">
+ <xsl:choose>
+ <xsl:when test="string-length(substring-before($name, '::')) &lt; string-length(substring-before($name, '&lt;'))">
+ <xsl:call-template name="strip-ns">
+ <xsl:with-param name="name" select="substring-after($name, '::')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="contains($name, '::')">
+ <xsl:call-template name="strip-ns">
+ <xsl:with-param name="name" select="substring-after($name, '::')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="cleanup-type">
+ <xsl:param name="name"/>
+ <xsl:variable name="type">
+ <xsl:choose>
+ <xsl:when test="contains($name, 'ASIO_DECL ')">
+ <xsl:value-of select="substring-after($name, 'ASIO_DECL ')"/>
+ </xsl:when>
+ <xsl:when test="contains($name, 'ASIO_DECL')">
+ <xsl:value-of select="substring-after($name, 'ASIO_DECL')"/>
+ </xsl:when>
+ <xsl:when test="$name = 'virtual'"></xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$type='void_or_deduced'">
+ <xsl:text>``[link asio.reference.asynchronous_operations.automatic_deduction_of_initiating_function_return_type ['DEDUCED]]``</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="make-id">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, 'boost::system::')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="substring-after($name, 'boost::system::')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, 'boost::asio::error::')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, 'boost::asio::error::'), substring-after($name, 'boost::asio::error::'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '::')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '::'), '__', substring-after($name, '::'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '=')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '='), '_eq_', substring-after($name, '='))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '!')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '!'), '_not_', substring-after($name, '!'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '-&gt;')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '-&gt;'), '_arrow_', substring-after($name, '-&gt;'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '&lt;')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '&lt;'), '_lt_', substring-after($name, '&lt;'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '&gt;')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '&gt;'), '_gt_', substring-after($name, '&gt;'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '[')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '['), '_lb_', substring-after($name, '['))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, ']')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, ']'), '_rb_', substring-after($name, ']'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '(')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '('), '_lp_', substring-after($name, '('))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, ')')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, ')'), '_rp_', substring-after($name, ')'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '+')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '+'), '_plus_', substring-after($name, '+'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '-')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '-'), '_minus_', substring-after($name, '-'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '*')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '*'), '_star_', substring-after($name, '*'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '~')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '~'), '_', substring-after($name, '~'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, ',')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, ','), '_comma_', substring-after($name, ','))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '...')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '...'), '_ellipsis_', substring-after($name, '...'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, ' ')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, ' '), '_', substring-after($name, ' '))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, 'boost__posix_time__ptime')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, 'boost__posix_time__ptime'), 'ptime', substring-after($name, 'boost__posix_time__ptime'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!--========== Markup ==========-->
+
+<xsl:template match="para" mode="markup">
+<xsl:text>
+</xsl:text><xsl:apply-templates mode="markup"/><xsl:text>
+</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="para" mode="markup-nested">
+<xsl:apply-templates mode="markup-nested"/>
+</xsl:template>
+
+
+<xsl:template match="title" mode="markup">
+ <xsl:variable name="title">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:if test="string-length($title) > 0">
+[heading <xsl:value-of select="."/>]
+ </xsl:if>
+</xsl:template>
+
+
+<xsl:template match="programlisting" mode="markup">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates mode="codeline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="programlisting" mode="markup-nested">
+ <xsl:value-of select="$newline"/>
+ <xsl:text>``</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates mode="codeline"/>
+ <xsl:if test="substring(., string-length(.)) = $newline">
+ <xsl:value-of select="$newline"/>
+ </xsl:if>
+ <xsl:text>``</xsl:text>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="codeline" mode="codeline">
+ <xsl:if test="string-length(.) &gt; 0">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:apply-templates mode="codeline"/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="sp" mode="markup">
+<xsl:text> </xsl:text>
+</xsl:template>
+
+
+<xsl:template match="sp" mode="markup-nested">
+<xsl:text> </xsl:text>
+</xsl:template>
+
+
+<xsl:template match="sp" mode="codeline">
+ <xsl:text> </xsl:text>
+</xsl:template>
+
+
+<xsl:template match="linebreak" mode="markup">
+<xsl:text>
+
+</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="linebreak" mode="markup-nested">
+<xsl:text>
+
+</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="computeroutput" mode="markup">
+<xsl:text>`</xsl:text><xsl:value-of select="."/><xsl:text>`</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="computeroutput" mode="markup-nested">
+<xsl:text>`</xsl:text><xsl:value-of select="."/><xsl:text>`</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="listitem" mode="markup">
+* <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text">
+ <xsl:apply-templates mode="markup"/>
+ </xsl:with-param>
+</xsl:call-template>
+</xsl:template>
+
+
+<xsl:template match="bold" mode="markup">[*<xsl:apply-templates mode="markup"/>]</xsl:template>
+
+
+<xsl:template match="emphasis" mode="markup">['<xsl:apply-templates mode="markup"/>]</xsl:template>
+
+
+<xsl:template match="parameterlist" mode="markup">
+ <xsl:choose>
+ <xsl:when test="@kind='param'">
+[heading Parameters]
+ </xsl:when>
+ <xsl:when test="@kind='exception'">
+[heading Exceptions]
+ </xsl:when>
+ </xsl:choose>
+
+[variablelist
+ <xsl:apply-templates mode="markup"/>
+]
+</xsl:template>
+
+
+<xsl:template match="parameteritem" mode="markup">
+[[<xsl:value-of select="parameternamelist"/>][<xsl:apply-templates select="parameterdescription" mode="markup-nested"/>]]
+</xsl:template>
+
+
+<xsl:template match="simplesect" mode="markup">
+ <xsl:choose>
+ <xsl:when test="@kind='return'">
+[heading Return Value]
+ <xsl:apply-templates mode="markup"/>
+ </xsl:when>
+ <xsl:when test="@kind='see'">
+ </xsl:when>
+ <xsl:when test="@kind='note'">
+[heading Remarks]
+ <xsl:apply-templates mode="markup"/>
+ </xsl:when>
+ <xsl:when test="@kind='par'">
+ <xsl:if test="not(starts-with(title, 'Concepts:'))">
+ <xsl:apply-templates mode="markup"/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="markup"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="text()" mode="markup">
+ <xsl:variable name="text" select="."/>
+ <xsl:variable name="starts-with-whitespace" select="
+ starts-with($text, ' ') or starts-with($text, $newline)"/>
+ <xsl:variable name="preceding-node-name">
+ <xsl:for-each select="preceding-sibling::*">
+ <xsl:if test="position() = last()">
+ <xsl:value-of select="local-name()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="after-newline" select="
+ $preceding-node-name = 'programlisting' or
+ $preceding-node-name = 'linebreak'"/>
+ <xsl:choose>
+ <xsl:when test="$starts-with-whitespace and $after-newline">
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="text()" mode="markup-nested">
+ <xsl:variable name="text" select="."/>
+ <xsl:variable name="starts-with-whitespace" select="
+ starts-with($text, ' ') or starts-with($text, $newline)"/>
+ <xsl:variable name="preceding-node-name">
+ <xsl:for-each select="preceding-sibling::*">
+ <xsl:if test="position() = last()">
+ <xsl:value-of select="local-name()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="after-newline" select="
+ $preceding-node-name = 'programlisting' or
+ $preceding-node-name = 'linebreak'"/>
+ <xsl:choose>
+ <xsl:when test="$starts-with-whitespace and $after-newline">
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="strip-leading-whitespace">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($text, ' ')">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="substring($text, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="starts-with($text, $newline)">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="substring($text, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="escape-text">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="contains($text, '_')">
+ <xsl:value-of select="substring-before($text, '_')"/>
+ <xsl:text>\_</xsl:text>
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text" select="substring-after($text, '_')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="escape-name">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="contains($text, '[')">
+ <xsl:value-of select="substring-before($text, '[')"/>
+ <xsl:text>\[</xsl:text>
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="substring-after($text, '[')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($text, ']')">
+ <xsl:value-of select="substring-before($text, ']')"/>
+ <xsl:text>\]</xsl:text>
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="substring-after($text, ']')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($text, '...')">
+ <xsl:value-of select="substring-before($text, '...')"/>
+ <xsl:text>\.\.\.</xsl:text>
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="substring-after($text, '...')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='compound']" mode="markup">
+ <xsl:variable name="name">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
+ <xsl:variable name="dox-ref-id" select="@refid"/>
+ <xsl:variable name="ref-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name"
+ select="(/doxygen//compounddef[@id=$dox-ref-id])[1]/compoundname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ref-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$ref-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>[link asio.reference.</xsl:text>
+ <xsl:value-of select="$ref-id"/>
+ <xsl:text> `</xsl:text>
+ <xsl:value-of name="text" select="$ref-name"/>
+ <xsl:text>`]</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>`</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>`</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='compound']" mode="markup-nested">
+ <xsl:variable name="name">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
+ <xsl:variable name="dox-ref-id" select="@refid"/>
+ <xsl:variable name="ref-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name"
+ select="(/doxygen//compounddef[@id=$dox-ref-id])[1]/compoundname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ref-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$ref-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>[link asio.reference.</xsl:text>
+ <xsl:value-of select="$ref-id"/>
+ <xsl:text> `</xsl:text>
+ <xsl:value-of name="text" select="$ref-name"/>
+ <xsl:text>`]</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>`</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>`</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='member']" mode="markup">
+ <xsl:variable name="dox-ref-id" select="@refid"/>
+ <xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
+ <xsl:choose>
+ <xsl:when test="contains(@refid, 'namespaceasio') and count($memberdefs) &gt; 0">
+ <xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
+ <xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
+ <xsl:variable name="ref-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ref-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$ref-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>[link asio.reference.</xsl:text>
+ <xsl:value-of select="$ref-id"/>
+ <xsl:text> `</xsl:text>
+ <xsl:value-of name="text" select="$ref-name"/>
+ <xsl:text>`]</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>`</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>`</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='member']" mode="markup-nested">
+ <xsl:variable name="dox-ref-id" select="@refid"/>
+ <xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
+ <xsl:choose>
+ <xsl:when test="contains(@refid, 'namespaceasio') and count($memberdefs) &gt; 0">
+ <xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
+ <xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
+ <xsl:variable name="ref-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ref-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$ref-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>[link asio.reference.</xsl:text>
+ <xsl:value-of select="$ref-id"/>
+ <xsl:text> `</xsl:text>
+ <xsl:value-of name="text" select="$ref-name"/>
+ <xsl:text>`]</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>`</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>`</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="header-requirements">
+ <xsl:param name="file"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text>[heading Requirements]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text>['Header: ]</xsl:text>
+ <xsl:text>[^asio/</xsl:text>
+ <xsl:value-of select="substring-after($file, 'include/asio/')"/>
+ <xsl:text>]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text>['Convenience header: ]</xsl:text>
+ <xsl:choose>
+ <xsl:when test="contains($file, 'include/asio/ssl')">
+ <xsl:text>[^asio/ssl.hpp]</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/high_resolution_timer')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/package')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/spawn')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/steady_timer')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/system_timer')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($file, 'include/asio/use_future')">
+ <xsl:text>None</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>[^asio.hpp]</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<!--========== Class ==========-->
+
+<xsl:template name="class">
+ <xsl:variable name="class-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="compoundname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="unqualified-class-name">
+ <xsl:call-template name="strip-ns">
+ <xsl:with-param name="name" select="compoundname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="class-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$class-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="class-file" select="location/@file"/>
+[section:<xsl:value-of select="$class-id"/><xsl:text> </xsl:text><xsl:value-of select="$class-name"/>]
+
+<xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+
+</xsl:text>
+
+<xsl:apply-templates select="templateparamlist"
+ mode="class-detail"/><xsl:text> </xsl:text><xsl:value-of select="@kind"/><xsl:text> </xsl:text><xsl:value-of
+ select="$unqualified-class-name"/><xsl:if test="count(basecompoundref[not(contains(.,'::detail'))]) > 0"> :</xsl:if><xsl:text>
+</xsl:text><xsl:for-each select="basecompoundref[not(contains(.,'::detail'))]">
+<xsl:text> </xsl:text><xsl:if test="@prot='public'">public </xsl:if><xsl:call-template
+ name="strip-asio-ns"><xsl:with-param name="name" select="."/></xsl:call-template><xsl:if
+ test="not(position() = last())">,</xsl:if><xsl:text>
+</xsl:text></xsl:for-each><xsl:text>
+</xsl:text>
+
+<xsl:call-template name="class-tables">
+ <xsl:with-param name="class-name" select="$class-name"/>
+ <xsl:with-param name="class-id" select="$class-id"/>
+</xsl:call-template>
+
+<xsl:apply-templates select="detaileddescription" mode="markup"/>
+
+<xsl:call-template name="header-requirements">
+ <xsl:with-param name="file" select="$class-file"/>
+</xsl:call-template>
+
+<xsl:call-template name="class-members">
+ <xsl:with-param name="class-name" select="$class-name"/>
+ <xsl:with-param name="class-id" select="$class-id"/>
+ <xsl:with-param name="class-file" select="$class-file"/>
+</xsl:call-template>
+
+[endsect]
+</xsl:template>
+
+
+<xsl:template name="class-tables">
+<xsl:param name="class-name"/>
+<xsl:param name="class-id"/>
+<xsl:if test="
+ count(
+ sectiondef[@kind='public-type'] |
+ innerclass[@prot='public' and not(contains(., '_handler'))]) &gt; 0">
+[heading Types]
+[table
+ [[Name][Description]]
+<xsl:for-each select="
+ sectiondef[@kind='public-type']/memberdef |
+ innerclass[@prot='public' and not(contains(., '_handler')) and not(contains(., 'thread_function'))]" mode="class-table">
+ <xsl:sort select="concat(name, (.)[not(name)])"/>
+ [
+<xsl:choose>
+ <xsl:when test="count(name) &gt; 0">
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="name"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="name"/>]]]
+ [<xsl:call-template name="escape-name"><xsl:with-param name="text" select="briefdescription"/></xsl:call-template>]
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="type-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="."/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="unqualified-type-name">
+ <xsl:call-template name="strip-ns">
+ <xsl:with-param name="name" select="."/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="type-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$type-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="type-ref-id" select="@refid"/>
+ [[link asio.reference.<xsl:value-of select="$type-id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$unqualified-type-name"/>]]]
+ [<xsl:value-of select="(/doxygen//compounddef[@id=$type-ref-id])[1]/briefdescription"/>]
+ </xsl:otherwise>
+</xsl:choose>
+ ]
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='public-func' or @kind='public-static-func']) > 0">
+[heading Member Functions]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='public-func' or @kind='public-static-func']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="escaped-name">
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$overload-position = 1">
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$escaped-name"/><xsl:text>]]]
+ [</xsl:text><xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="not($overload-position = 1) and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="$overload-position = $overload-count">
+ <xsl:text>]
+ ]
+ </xsl:text>
+ </xsl:if>
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='protected-func' or @kind='protected-static-func']) > 0">
+[heading Protected Member Functions]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='protected-func' or @kind='protected-static-func']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$overload-position = 1">
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$name"/><xsl:text>]]]
+ [</xsl:text><xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="not($overload-position = 1) and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="$overload-position = $overload-count">
+ <xsl:text>]
+ ]
+ </xsl:text>
+ </xsl:if>
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="$class-name = 'execution_context::service'">
+<xsl:if test="count(sectiondef[@kind='private-func']) > 0">
+[heading Private Member Functions]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='private-func']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$overload-position = 1">
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$name"/><xsl:text>]]]
+ [</xsl:text><xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="not($overload-position = 1) and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="$overload-position = $overload-count">
+ <xsl:text>]
+ ]
+ </xsl:text>
+ </xsl:if>
+</xsl:for-each>
+]
+</xsl:if>
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='public-attrib' or @kind='public-static-attrib']) > 0">
+[heading Data Members]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='public-attrib' or @kind='public-static-attrib']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="name"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="name"/>]]]
+ [<xsl:value-of select="briefdescription"/>]
+ ]
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='protected-attrib' or @kind='protected-static-attrib']) > 0">
+[heading Protected Data Members]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='protected-attrib' or @kind='protected-static-attrib']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="name"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="name"/>]]]
+ [<xsl:value-of select="briefdescription"/>]
+ ]
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='friend']/memberdef[not(type = 'friend class') and not(contains(name, '_helper'))]) &gt; 0">
+[heading Friends]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='friend']/memberdef[not(type = 'friend class') and not(contains(name, '_helper'))]" mode="class-table">
+ <xsl:sort select="name"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$overload-position = 1">
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$name"/><xsl:text>]]]
+ [</xsl:text><xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="not($overload-position = 1) and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="$overload-position = $overload-count">
+ <xsl:text>]
+ ]
+ </xsl:text>
+ </xsl:if>
+</xsl:for-each>
+]
+</xsl:if>
+
+<xsl:if test="count(sectiondef[@kind='related']/memberdef) &gt; 0">
+[heading Related Functions]
+[table
+ [[Name][Description]]
+<xsl:for-each select="sectiondef[@kind='related']/memberdef" mode="class-table">
+ <xsl:sort select="name"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$overload-position = 1">
+ [
+ [[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>
+ <xsl:text> </xsl:text>[*<xsl:value-of select="$name"/><xsl:text>]]]
+ [</xsl:text><xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="not($overload-position = 1) and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="briefdescription"/>
+ </xsl:if>
+ <xsl:if test="$overload-position = $overload-count">
+ <xsl:text>]
+ ]
+ </xsl:text>
+ </xsl:if>
+</xsl:for-each>
+]
+</xsl:if>
+
+</xsl:template>
+
+
+<xsl:template name="class-members">
+<xsl:param name="class-name"/>
+<xsl:param name="class-id"/>
+<xsl:param name="class-file"/>
+<xsl:apply-templates select="sectiondef[@kind='public-type' or @kind='public-func' or @kind='public-static-func' or @kind='public-attrib' or @kind='public-static-attrib' or @kind='protected-func' or @kind='protected-static-func' or @kind='protected-attrib' or @kind='protected-static-attrib' or @kind='friend' or @kind='related']/memberdef[not(type = 'friend class') and not(contains(name, '_helper'))]" mode="class-detail">
+ <xsl:sort select="name"/>
+ <xsl:with-param name="class-name" select="$class-name"/>
+ <xsl:with-param name="class-id" select="$class-id"/>
+ <xsl:with-param name="class-file" select="$class-file"/>
+</xsl:apply-templates>
+<xsl:if test="$class-name = 'execution_context::service'">
+ <xsl:apply-templates select="sectiondef[@kind='private-func']/memberdef[not(type = 'friend class') and not(contains(name, '_helper'))]" mode="class-detail">
+ <xsl:sort select="name"/>
+ <xsl:with-param name="class-name" select="$class-name"/>
+ <xsl:with-param name="class-id" select="$class-id"/>
+ <xsl:with-param name="class-file" select="$class-file"/>
+ </xsl:apply-templates>
+</xsl:if>
+</xsl:template>
+
+
+<!-- Class detail -->
+
+<xsl:template match="memberdef" mode="class-detail">
+ <xsl:param name="class-name"/>
+ <xsl:param name="class-id"/>
+ <xsl:param name="class-file"/>
+ <xsl:variable name="name">
+ <xsl:value-of select="name"/>
+ </xsl:variable>
+ <xsl:variable name="escaped-name">
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="escaped-class-name">
+ <xsl:call-template name="escape-name">
+ <xsl:with-param name="text" select="$class-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+<xsl:if test="$overload-count &gt; 1 and $overload-position = 1">
+[section:<xsl:value-of select="$id"/><xsl:text> </xsl:text>
+<xsl:value-of select="$class-name"/>::<xsl:value-of select="$escaped-name"/>]
+
+<xsl:text>[indexterm2 </xsl:text>
+<xsl:text>asio.indexterm.</xsl:text>
+<xsl:value-of select="$class-id"/>
+<xsl:text>.</xsl:text>
+<xsl:value-of select="$id"/>
+<xsl:text>..</xsl:text>
+<xsl:value-of select="$escaped-name"/>
+<xsl:text>..</xsl:text>
+<xsl:value-of select="$escaped-class-name"/>
+<xsl:text>] </xsl:text>
+
+<xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+</xsl:text>
+
+<xsl:for-each select="../memberdef[name = $name]">
+<xsl:if test="position() &gt; 1 and not(briefdescription = preceding-sibling::*/briefdescription)">
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates select="briefdescription" mode="markup"/>
+ <xsl:value-of select="$newline"/>
+</xsl:if>
+<xsl:text>
+</xsl:text><xsl:apply-templates select="templateparamlist" mode="class-detail"/>
+<xsl:text> </xsl:text>
+ <xsl:if test="@explicit='yes'">explicit </xsl:if>
+ <xsl:if test="@static='yes'">static </xsl:if>
+ <xsl:if test="@virt='virtual'">virtual </xsl:if>
+ <xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length($stripped-type) &gt; 0">
+ <xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text>
+</xsl:if>``[link asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of
+ select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text><xsl:value-of
+ select="name"/>]``(<xsl:apply-templates select="param"
+ mode="class-detail"/>)<xsl:if test="@const='yes'"> const</xsl:if>;
+<xsl:text> `` [''''&amp;raquo;'''</xsl:text>
+<xsl:text> [link asio.reference.</xsl:text>
+<xsl:value-of select="$class-id"/>.<xsl:value-of
+ select="$id"/>.overload<xsl:value-of select="position()"/>
+<xsl:text> more...]]``
+</xsl:text>
+</xsl:for-each>
+</xsl:if>
+
+[section:<xsl:if test="$overload-count = 1"><xsl:value-of select="$id"/></xsl:if>
+<xsl:if test="$overload-count &gt; 1">overload<xsl:value-of select="$overload-position"/></xsl:if>
+<xsl:text> </xsl:text><xsl:value-of select="$class-name"/>::<xsl:value-of select="$escaped-name"/>
+<xsl:if test="$overload-count &gt; 1"> (<xsl:value-of
+ select="$overload-position"/> of <xsl:value-of select="$overload-count"/> overloads)</xsl:if>]
+
+<xsl:if test="not(starts-with($doxygen-id, ../../@id))">
+<xsl:variable name="inherited-from" select="/doxygen/compounddef[starts-with($doxygen-id, @id)]/compoundname"/>
+<xsl:if test="not(contains($inherited-from, '::detail'))">
+['Inherited from <xsl:call-template name="strip-asio-ns">
+<xsl:with-param name="name" select="$inherited-from"/>
+</xsl:call-template>.]<xsl:text>
+
+</xsl:text></xsl:if></xsl:if>
+
+<xsl:if test="$overload-count = 1">
+ <xsl:text>[indexterm2 </xsl:text>
+ <xsl:text>asio.indexterm.</xsl:text>
+ <xsl:value-of select="$class-id"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="$id"/>
+ <xsl:text>..</xsl:text>
+ <xsl:value-of select="$escaped-name"/>
+ <xsl:text>..</xsl:text>
+ <xsl:value-of select="$escaped-class-name"/>
+ <xsl:text>] </xsl:text>
+</xsl:if>
+
+<xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="@kind='typedef'">
+ <xsl:call-template name="typedef" mode="class-detail">
+ <xsl:with-param name="class-name" select="$class-name"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@kind='variable'">
+ <xsl:call-template name="variable" mode="class-detail"/>
+ </xsl:when>
+ <xsl:when test="@kind='enum'">
+ <xsl:call-template name="enum" mode="class-detail">
+ <xsl:with-param name="enum-name" select="$class-name"/>
+ <xsl:with-param name="id" select="concat($class-id, '.', $id)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@kind='function'">
+ <xsl:call-template name="function" mode="class-detail"/>
+ </xsl:when>
+ <xsl:when test="@kind='friend'">
+ <xsl:call-template name="function" mode="class-detail"/>
+ </xsl:when>
+ </xsl:choose>
+
+<xsl:text>
+</xsl:text><xsl:apply-templates select="detaileddescription" mode="markup"/>
+
+<xsl:if test="@kind='typedef' or @kind='friend'">
+ <xsl:call-template name="header-requirements">
+ <xsl:with-param name="file" select="$class-file"/>
+ </xsl:call-template>
+</xsl:if>
+
+[endsect]
+
+<xsl:if test="$overload-count &gt; 1 and $overload-position = $overload-count">
+[endsect]
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template name="typedef">
+<xsl:param name="class-name"/>
+<xsl:text>
+ </xsl:text>typedef <xsl:value-of select="type"/><xsl:text> </xsl:text><xsl:value-of select="name"/>;<xsl:text>
+
+</xsl:text>
+<xsl:if test="count(type/ref) &gt; 0 and not(contains(type, '*'))">
+ <xsl:variable name="class-refid">
+ <xsl:for-each select="type/ref[1]">
+ <xsl:value-of select="@refid"/>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="name" select="name"/>
+ <xsl:for-each select="/doxygen/compounddef[@id=$class-refid]">
+ <xsl:call-template name="class-tables">
+ <xsl:with-param name="class-name">
+ <xsl:value-of select="concat($class-name, '::', $name)"/>
+ </xsl:with-param>
+ <xsl:with-param name="class-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="compoundname"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:apply-templates select="detaileddescription" mode="markup"/>
+ </xsl:for-each>
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template name="variable">
+<xsl:text>
+ </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:value-of
+ select="type"/><xsl:text> </xsl:text><xsl:value-of select="name"/>
+ <xsl:if test="count(initializer) = 1"><xsl:text> =</xsl:text>
+ <xsl:value-of select="initializer"/></xsl:if>;
+</xsl:template>
+
+
+<xsl:template name="enum">
+<xsl:param name="enum-name"/>
+<xsl:param name="id"/>
+ enum <xsl:value-of select="name"/><xsl:text>
+</xsl:text><xsl:if test="count(enumvalue) &gt; 0">
+<xsl:value-of select="$newline"/>
+<xsl:for-each select="enumvalue">
+ <xsl:text>[indexterm2 </xsl:text>
+ <xsl:text>asio.indexterm.</xsl:text>
+ <xsl:value-of select="$id"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="name"/>
+ <xsl:text>..</xsl:text>
+ <xsl:value-of select="name"/>
+ <xsl:text>..</xsl:text>
+ <xsl:value-of select="$enum-name"/>
+ <xsl:text>]</xsl:text>
+ <xsl:value-of select="$newline"/>
+</xsl:for-each>
+[heading Values]
+[variablelist
+<xsl:for-each select="enumvalue">
+ [
+ [<xsl:value-of select="name"/>]
+ [<xsl:value-of select="briefdescription"/>]
+ ]
+</xsl:for-each>
+]
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template name="function">
+<xsl:text>
+</xsl:text>
+<xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+</xsl:variable>
+<xsl:choose>
+ <xsl:when test="count(/doxygen//memberdef[@id=$doxygen-id]/templateparamlist) = 1">
+ <xsl:apply-templates select="/doxygen//memberdef[@id=$doxygen-id]/templateparamlist" mode="class-detail"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="templateparamlist" mode="class-detail"/>
+ </xsl:otherwise>
+</xsl:choose>
+<xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+</xsl:variable>
+<xsl:text> </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:if
+ test="@virt='virtual'">virtual </xsl:if><xsl:if
+ test="string-length($stripped-type) &gt; 0"><xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>
+<xsl:value-of select="name"/>(<xsl:apply-templates select="param"
+ mode="class-detail"/>)<xsl:if test="@const='yes'"> const</xsl:if>;
+</xsl:template>
+
+
+<xsl:template match="templateparamlist" mode="class-detail">
+<xsl:text> </xsl:text>template&lt;<xsl:apply-templates select="param" mode="class-detail-template"/>&gt;
+</xsl:template>
+
+
+<xsl:template match="param" mode="class-detail-template">
+<xsl:text>
+ </xsl:text><xsl:value-of select="type"/><xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test="declname = 'Allocator'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Arg'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Args'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'BufferSequence'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'ByteType'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'C'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Clock'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'CompletionToken'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Context_Service'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Duration'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'DatagramSocketService1'">
+ <xsl:value-of select="concat('``[link asio.reference.DatagramSocketService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'EndpointIterator'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Elem'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'ErrorEnum'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'ExecutionContext'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Executor'">
+ <xsl:value-of select="concat('``[link asio.reference.Executor1 ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Function'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Iterator'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'MatchCondition'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'N'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'OtherAllocator'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'OtherExecutor'">
+ <xsl:value-of select="concat('``[link asio.reference.Executor1 ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'OtherHandler'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'PasswordCallback'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Period'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'PodType'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'PointerToPodType'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Protocol1'">
+ <xsl:value-of select="concat('``[link asio.reference.Protocol ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'RawSocketService1'">
+ <xsl:value-of select="concat('``[link asio.reference.RawSocketService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Rep'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Result'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'SeqPacketSocketService1'">
+ <xsl:value-of select="concat('``[link asio.reference.SeqPacketSocketService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Signature'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'SocketAcceptorService1' or declname = 'SocketAcceptorService2'">
+ <xsl:value-of select="concat('``[link asio.reference.SocketAcceptorService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'SocketService1' or declname = 'SocketService2'">
+ <xsl:value-of select="concat('``[link asio.reference.SocketService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Stream'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'StreamSocketService1'">
+ <xsl:value-of select="concat('``[link asio.reference.StreamSocketService ', declname, ']``')"/>
+ </xsl:when>
+ <xsl:when test="declname = 'T'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'T1'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'TN'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Time'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'TimeType'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'Traits'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'U'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="declname = 'VerifyCallback'">
+ <xsl:value-of select="declname"/>
+ </xsl:when>
+ <xsl:when test="count(declname) = 0">
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('``[link asio.reference.', declname, ' ', declname, ']``')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="count(defval) > 0"> = <xsl:value-of
+ select="defval"/></xsl:if><xsl:if test="not(position() = last())">,</xsl:if>
+</xsl:template>
+
+
+<xsl:template match="param" mode="class-detail">
+<xsl:text>
+ </xsl:text>
+ <xsl:choose>
+ <xsl:when test="string-length(array) &gt; 0">
+ <xsl:value-of select="substring-before(type, '&amp;')"/>
+ <xsl:text>(&amp;</xsl:text>
+ <xsl:value-of select="declname"/>
+ <xsl:text>)</xsl:text>
+ <xsl:value-of select="array"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="type"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="declname"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="count(defval) > 0"> = <xsl:value-of select="defval"/></xsl:if>
+ <xsl:if test="not(position() = last())">,</xsl:if>
+</xsl:template>
+
+
+<xsl:template match="*" mode="class-detail"/>
+
+
+<!--========== Namespace ==========-->
+
+<xsl:template name="namespace-memberdef">
+ <xsl:variable name="name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="concat(../../compoundname, '::', name)"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="unqualified-name">
+ <xsl:call-template name="strip-ns">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="doxygen-id">
+ <xsl:value-of select="@id"/>
+ </xsl:variable>
+ <xsl:variable name="overload-count">
+ <xsl:value-of select="count(../memberdef[name = $unqualified-name])"/>
+ </xsl:variable>
+ <xsl:variable name="overload-position">
+ <xsl:for-each select="../memberdef[name = $unqualified-name]">
+ <xsl:if test="@id = $doxygen-id">
+ <xsl:value-of select="position()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+<xsl:if test="$overload-count &gt; 1 and $overload-position = 1">
+[section:<xsl:value-of select="$id"/><xsl:text> </xsl:text><xsl:value-of select="$name"/>]
+
+<xsl:text>[indexterm1 </xsl:text>
+<xsl:text>asio.indexterm.</xsl:text>
+<xsl:value-of select="$id"/>
+<xsl:text>..</xsl:text>
+<xsl:value-of select="$name"/>
+<xsl:text>] </xsl:text>
+
+<xsl:choose>
+ <xsl:when test="count(/doxygen/compounddef[@kind='group' and compoundname=$name]) &gt; 0">
+ <xsl:for-each select="/doxygen/compounddef[@kind='group' and compoundname=$name]">
+ <xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+ </xsl:text>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+ </xsl:text>
+ </xsl:otherwise>
+</xsl:choose>
+
+<xsl:for-each select="../memberdef[name = $unqualified-name]">
+<xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+</xsl:variable>
+<xsl:text>
+</xsl:text><xsl:apply-templates select="templateparamlist" mode="class-detail"/>
+<xsl:text> </xsl:text><xsl:if test="string-length($stripped-type) &gt; 0"><xsl:value-of
+ select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>``[link asio.reference.<xsl:value-of
+ select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text>
+<xsl:value-of select="name"/>]``(<xsl:apply-templates select="param" mode="class-detail"/>);
+<xsl:text> `` [''''&amp;raquo;'''</xsl:text>
+<xsl:text> [link asio.reference.</xsl:text>
+<xsl:value-of select="$id"/>.overload<xsl:value-of select="position()"/>
+<xsl:text> more...]]``
+</xsl:text>
+</xsl:for-each>
+
+<xsl:for-each select="/doxygen/compounddef[@kind='group' and compoundname=$name]">
+ <xsl:apply-templates select="detaileddescription" mode="markup"/>
+</xsl:for-each>
+
+<xsl:call-template name="header-requirements">
+ <xsl:with-param name="file" select="location/@file"/>
+</xsl:call-template>
+
+</xsl:if>
+
+[section:<xsl:if test="$overload-count = 1"><xsl:value-of select="$id"/></xsl:if>
+<xsl:if test="$overload-count &gt; 1">overload<xsl:value-of select="$overload-position"/>
+</xsl:if><xsl:text> </xsl:text><xsl:value-of select="$name"/>
+<xsl:if test="$overload-count &gt; 1"> (<xsl:value-of
+ select="$overload-position"/> of <xsl:value-of select="$overload-count"/> overloads)</xsl:if>]
+
+<xsl:if test="$overload-count = 1">
+ <xsl:text>[indexterm1 </xsl:text>
+ <xsl:text>asio.indexterm.</xsl:text>
+ <xsl:value-of select="$id"/>
+ <xsl:text>..</xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>] </xsl:text>
+</xsl:if>
+
+<xsl:apply-templates select="briefdescription" mode="markup"/><xsl:text>
+</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="@kind='typedef'">
+ <xsl:call-template name="typedef">
+ <xsl:with-param name="class-name" select="$name"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@kind='variable'">
+ <xsl:call-template name="variable"/>
+ </xsl:when>
+ <xsl:when test="@kind='enum'">
+ <xsl:call-template name="enum">
+ <xsl:with-param name="enum-name" select="$name"/>
+ <xsl:with-param name="id" select="$id"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@kind='function'">
+ <xsl:call-template name="function"/>
+ </xsl:when>
+ </xsl:choose>
+
+<xsl:text>
+</xsl:text><xsl:apply-templates select="detaileddescription" mode="markup"/>
+
+<xsl:if test="$overload-count = 1">
+ <xsl:call-template name="header-requirements">
+ <xsl:with-param name="file" select="location/@file"/>
+ </xsl:call-template>
+</xsl:if>
+
+[endsect]
+
+<xsl:if test="$overload-count &gt; 1 and $overload-position = $overload-count">
+[endsect]
+</xsl:if>
+</xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/3rdparty/asio/src/doc/release_checklist.htm b/3rdparty/asio/src/doc/release_checklist.htm
new file mode 100644
index 00000000000..3ce2cbe8c53
--- /dev/null
+++ b/3rdparty/asio/src/doc/release_checklist.htm
@@ -0,0 +1,68 @@
+<html>
+ <head>
+ <title>asio Release Checklist</title>
+ </head>
+ <body>
+ <h1>asio Release Checklist</h1>
+ <form>
+ <table border="1">
+ <tr>
+ <td>Update version number in configure.ac</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Update version number and date in README</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Generate a clean distribution by doing a `make maintainer-clean`
+ followed by the steps necessary to do a `make dist'</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution on Mac OS X using g++ 4.0 with
+ adjacent boost directory</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution on Linux using g++ 3.4 using the
+ `--with-boost' configure option</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution on Solaris using g++ 3.3 with
+ adjacent boost directory</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution using MSVC 7.1 with adjacent boost
+ directory</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution using bcc32 5.6.4 with adjacent
+ boost directory</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Unpack/build/test distribution using MinGW-4.1.0 with adjacent
+ boost directory</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Commit version number changes to CVS</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Apply CVS tag of the form asio-x-y-z</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ <tr>
+ <td>Generate a clean distribution by doing a `make maintainer-clean`
+ followed by the steps necessary to do a `make dist'</td>
+ <td><input type="checkbox"></td>
+ </tr>
+ </table>
+ </form>
+ </body>
+</html>
diff --git a/3rdparty/asio/src/doc/requirements/AcceptHandler.qbk b/3rdparty/asio/src/doc/requirements/AcceptHandler.qbk
new file mode 100644
index 00000000000..ae5ea3f0388
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AcceptHandler.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AcceptHandler Accept handler requirements]
+
+An accept handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of an accept handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as an accept handler:
+
+ void accept_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+
+An accept handler function object:
+
+ struct accept_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as an accept handler:
+
+ acceptor.async_accept(...,
+ [](const asio::error_code& ec)
+ {
+ ...
+ });
+
+A non-static class member function adapted to an accept handler using
+`std::bind()`:
+
+ void my_class::accept_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ acceptor.async_accept(...,
+ std::bind(&my_class::accept_handler,
+ this, std::placeholders::_1));
+
+A non-static class member function adapted to an accept handler using
+`boost::bind()`:
+
+ void my_class::accept_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ acceptor.async_accept(...,
+ boost::bind(&my_class::accept_handler,
+ this, asio::placeholders::error));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/AcceptableProtocol.qbk b/3rdparty/asio/src/doc/requirements/AcceptableProtocol.qbk
new file mode 100644
index 00000000000..37683879adf
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AcceptableProtocol.qbk
@@ -0,0 +1,25 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AcceptableProtocol Acceptable protocol requirements]
+
+A type `X` meets the `AcceptableProtocol` requirements if it satisfies the
+requirements of [link asio.reference.Protocol `Protocol`] as well as the
+additional requirements listed below.
+
+[table AcceptableProtocol requirements
+ [[expression] [return type] [assertion/note\npre/post-conditions]]
+ [
+ [`X::socket`]
+ [A type that satisfies the requirements of `Destructible` (C++Std
+ \[destructible\]) and `MoveConstructible` (C++Std \[moveconstructible\]),
+ and that is publicly and unambiguously derived from `basic_socket<X>`.]
+ []
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/AsyncRandomAccessReadDevice.qbk b/3rdparty/asio/src/doc/requirements/AsyncRandomAccessReadDevice.qbk
new file mode 100644
index 00000000000..4109c0157dc
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AsyncRandomAccessReadDevice.qbk
@@ -0,0 +1,56 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AsyncRandomAccessReadDevice Buffer-oriented asynchronous random-access
+read device requirements]
+
+In the table below, `a` denotes an asynchronous random access read device
+object, `o` denotes an offset of type `boost::uint64_t`, `mb` denotes an object
+satisfying [link asio.reference.MutableBufferSequence mutable buffer sequence]
+requirements, and `h` denotes an object satisfying [link
+asio.reference.ReadHandler read handler] requirements.
+
+[table Buffer-oriented asynchronous random-access read device requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.get_executor()`]
+ [A type satisfying the [link asio.reference.Executor1 Executor requirements].]
+ [Returns the associated I/O executor.]
+ ]
+ [
+ [`a.async_read_some_at(o, mb, h);`]
+ [`void`]
+ [
+ Initiates an asynchronous operation to read one or more bytes of data
+ from the device `a` at the offset `o`. The operation is performed via the
+ `io_service` object `a.get_io_service()` and behaves according to [link
+ asio.reference.asynchronous_operations asynchronous operation]
+ requirements.\n
+ \n
+ The mutable buffer sequence `mb` specifies memory where the data should
+ be placed. The `async_read_some_at` operation shall always fill a buffer
+ in the sequence completely before proceeding to the next.\n
+ \n
+ The implementation shall maintain one or more copies of `mb` until such
+ time as the read operation no longer requires access to the memory
+ specified by the buffers in the sequence. The program must ensure the
+ memory is valid until:\n
+ \n
+ [mdash] the last copy of `mb` is destroyed, or\n
+ \n
+ [mdash] the handler for the asynchronous read operation is invoked,\n
+ \n
+ whichever comes first.\n
+ \n
+ If the total size of all buffers in the sequence `mb` is `0`, the
+ asynchronous read operation shall complete immediately and pass `0` as
+ the argument to the handler that specifies the number of bytes read.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/AsyncRandomAccessWriteDevice.qbk b/3rdparty/asio/src/doc/requirements/AsyncRandomAccessWriteDevice.qbk
new file mode 100644
index 00000000000..bd9ecbd834b
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AsyncRandomAccessWriteDevice.qbk
@@ -0,0 +1,57 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AsyncRandomAccessWriteDevice Buffer-oriented asynchronous
+random-access write device requirements]
+
+In the table below, `a` denotes an asynchronous write stream object, `o`
+denotes an offset of type `boost::uint64_t`, `cb` denotes an object satisfying
+[link asio.reference.ConstBufferSequence constant buffer sequence]
+requirements, and `h` denotes an object satisfying [link
+asio.reference.WriteHandler write handler] requirements.
+
+[table Buffer-oriented asynchronous random-access write device requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.get_executor()`]
+ [A type satisfying the [link asio.reference.Executor1 Executor requirements].]
+ [Returns the associated I/O executor.]
+ ]
+ [
+ [`a.async_write_some_at(o, cb, h);`]
+ [`void`]
+ [
+ Initiates an asynchronous operation to write one or more bytes of data to
+ the device `a` at offset `o`. The operation is performed via the
+ `io_service` object `a.get_io_service()` and behaves according to [link
+ asio.reference.asynchronous_operations asynchronous operation]
+ requirements.\n
+ \n
+ The constant buffer sequence `cb` specifies memory where the data to be
+ written is located. The `async_write_some_at` operation shall always
+ write a buffer in the sequence completely before proceeding to the
+ next.\n
+ \n
+ The implementation shall maintain one or more copies of `cb` until such
+ time as the write operation no longer requires access to the memory
+ specified by the buffers in the sequence. The program must ensure the
+ memory is valid until:\n
+ \n
+ [mdash] the last copy of `cb` is destroyed, or\n
+ \n
+ [mdash] the handler for the asynchronous write operation is invoked,\n
+ \n
+ whichever comes first.\n
+ \n
+ If the total size of all buffers in the sequence `cb` is `0`, the
+ asynchronous write operation shall complete immediately and pass `0` as
+ the argument to the handler that specifies the number of bytes written.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/AsyncReadStream.qbk b/3rdparty/asio/src/doc/requirements/AsyncReadStream.qbk
new file mode 100644
index 00000000000..0fcd42f9c14
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AsyncReadStream.qbk
@@ -0,0 +1,50 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AsyncReadStream Buffer-oriented asynchronous read stream requirements]
+
+A type `X` meets the `AsyncReadStream` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a value of type `X`, `mb` denotes a (possibly
+const) value satisfying the [link asio.reference.MutableBufferSequence
+`MutableBufferSequence`] requirements, and `t` is a completion token.
+
+[table AsyncReadStream requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.get_executor()`]
+ [A type satisfying the [link asio.reference.Executor1 Executor requirements].]
+ [Returns the associated I/O executor.]
+ ]
+ [
+ [`a.async_read_some(mb,t)`]
+ [
+ The return type is determined according to the requirements for an
+ [link asio.reference.asynchronous_operations asynchronous operation].
+ ]
+ [
+ Meets the requirements for a [link asio.reference.read_write_operations
+ read operation] and an [link asio.reference.asynchronous_operations
+ asynchronous operation] with completion signature `void(error_code ec,
+ size_t n)`.\n
+ \n
+ If `buffer_size(mb) > 0`, initiates an asynchronous operation to read one
+ or more bytes of data from the stream `a` into the buffer sequence `mb`.
+ If successful, `ec` is set such that `!ec` is `true`, and `n` is the
+ number of bytes read. If an error occurred, `ec` is set such that `!!ec`
+ is `true`, and `n` is 0. If all data has been read from the stream, and
+ the stream performed an orderly shutdown, `ec` is
+ `stream_errc::eof` and `n` is 0.\n
+ \n
+ If `buffer_size(mb) == 0`, the operation completes immediately. `ec` is
+ set such that `!ec` is `true`, and `n` is 0.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/AsyncWriteStream.qbk b/3rdparty/asio/src/doc/requirements/AsyncWriteStream.qbk
new file mode 100644
index 00000000000..ee53b238c11
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/AsyncWriteStream.qbk
@@ -0,0 +1,48 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:AsyncWriteStream Buffer-oriented asynchronous write stream requirements]
+
+A type `X` meets the `AsyncWriteStream` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a value of type `X`, `cb` denotes a (possibly
+const) value satisfying the [link asio.reference.ConstBufferSequence
+`ConstBufferSequence`] requirements, and `t` is a completion token.
+
+[table AsyncWriteStream requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.get_executor()`]
+ [A type satisfying the [link asio.reference.Executor1 Executor requirements].]
+ [Returns the associated I/O executor.]
+ ]
+ [
+ [`a.async_write_some(cb,t)`]
+ [
+ The return type is determined according to the requirements for an
+ [link asio.reference.asynchronous_operations asynchronous operation].
+ ]
+ [
+ Meets the requirements for a [link asio.reference.read_write_operations
+ write operation] and an [link asio.reference.asynchronous_operations
+ asynchronous operation] with completion signature `void(error_code ec,
+ size_t n)`.\n
+ \n
+ If `buffer_size(cb) > 0`, initiates an asynchronous operation to write
+ one or more bytes of data to the stream `a` from the buffer sequence
+ `cb`. If successful, `ec` is set such that `!ec` is `true`, and `n` is
+ the number of bytes written. If an error occurred, `ec` is set such that
+ `!!ec` is `true`, and `n` is 0.\n
+ \n
+ If `buffer_size(cb) == 0`, the operation completes immediately. `ec` is
+ set such that `!ec` is `true`, and `n` is 0.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/BufferedHandshakeHandler.qbk b/3rdparty/asio/src/doc/requirements/BufferedHandshakeHandler.qbk
new file mode 100644
index 00000000000..6e6bbf231c3
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/BufferedHandshakeHandler.qbk
@@ -0,0 +1,55 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:BufferedHandshakeHandler Buffered handshake handler requirements]
+
+A buffered handshake handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a buffered handshake handler
+class should work correctly in the expression `h(ec, s)`, where `ec` is an
+lvalue of type `const error_code` and `s` is an lvalue of type `const size_t`.
+
+[heading Examples]
+
+A free function as a buffered handshake handler:
+
+ void handshake_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+
+A buffered handshake handler function object:
+
+ struct handshake_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ };
+
+A non-static class member function adapted to a buffered handshake handler
+using `boost::bind()`:
+
+ void my_class::handshake_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ socket.async_handshake(...,
+ boost::bind(&my_class::handshake_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/CompletionCondition.qbk b/3rdparty/asio/src/doc/requirements/CompletionCondition.qbk
new file mode 100644
index 00000000000..157561380b5
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/CompletionCondition.qbk
@@ -0,0 +1,42 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:CompletionCondition Completion condition requirements]
+
+A ['completion condition] is a function object that is used with the algorithms
+[link asio.reference.read `read`], [link asio.reference.async_read
+`async_read`], [link asio.reference.write `write`], and [link
+asio.reference.async_write `async_write`] to determine when the algorithm has
+completed transferring data.
+
+A type `X` meets the `CompletionCondition` requirements if it satisfies the
+requirements of `Destructible` (C++Std [destructible]) and
+`CopyConstructible` (C++Std [copyconstructible]), as well as the additional
+requirements listed below.
+
+In the table below, `x` denotes a value of type `X`, `ec` denotes a (possibly
+const) value of type `error_code`, and `n` denotes a (possibly const) value of
+type `size_t`.
+
+[table CompletionCondition requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`x(ec, n)`]
+ [`size_t`]
+ [
+ Let `n` be the total number of bytes transferred by the read or write
+ algorithm so far.\n
+ \n
+ Returns the maximum number of bytes to be transferred on the next
+ `read_some`, `async_read_some`, `write_some`, or `async_write_some`
+ operation performed by the algorithm. Returns `0` to indicate that the
+ algorithm is complete.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/CompletionHandler.qbk b/3rdparty/asio/src/doc/requirements/CompletionHandler.qbk
new file mode 100644
index 00000000000..28d158b6cdd
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/CompletionHandler.qbk
@@ -0,0 +1,63 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:CompletionHandler Completion handler requirements]
+
+A completion handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a completion handler
+class should work correctly in the expression `h()`.
+
+[heading Examples]
+
+A free function as a completion handler:
+
+ void completion_handler()
+ {
+ ...
+ }
+
+A completion handler function object:
+
+ struct completion_handler
+ {
+ ...
+ void operator()()
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a completion handler:
+
+ my_io_service.post(
+ []()
+ {
+ ...
+ });
+
+A non-static class member function adapted to a completion handler using
+`std::bind()`:
+
+ void my_class::completion_handler()
+ {
+ ...
+ }
+ ...
+ my_io_service.post(std::bind(&my_class::completion_handler, this));
+
+A non-static class member function adapted to a completion handler using
+`boost::bind()`:
+
+ void my_class::completion_handler()
+ {
+ ...
+ }
+ ...
+ my_io_service.post(boost::bind(&my_class::completion_handler, this));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ConnectCondition.qbk b/3rdparty/asio/src/doc/requirements/ConnectCondition.qbk
new file mode 100644
index 00000000000..995398c31d2
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ConnectCondition.qbk
@@ -0,0 +1,34 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ConnectCondition Connect condition requirements]
+
+A type `X` meets the `ConnectCondition` requirements if it satisfies the
+requirements of `Destructible` (C++Std [destructible]) and
+`CopyConstructible` (C++Std [copyconstructible]), as well as the additional
+requirements listed below.
+
+In the table below, `x` denotes a value of type `X`, `ec` denotes a (possibly
+const) value of type `error_code`, and `ep` denotes a (possibly const) value of
+some type satisfying the [link asio.reference.Endpoint endpoint] requirements.
+
+[table ConnectCondition requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`x(ec, ep)`]
+ [`bool`]
+ [
+ Returns `true` to indicate that the `connect` or `async_connect`
+ algorithm should attempt a connection to the endpoint `ep`. Otherwise,
+ returns `false` to indicate that the algorithm should not attempt
+ connection to the endpoint `ep`, and should instead skip to the next
+ endpoint in the sequence.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ConnectHandler.qbk b/3rdparty/asio/src/doc/requirements/ConnectHandler.qbk
new file mode 100644
index 00000000000..14b57d251d6
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ConnectHandler.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ConnectHandler Connect handler requirements]
+
+A connect handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a connect handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as a connect handler:
+
+ void connect_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+
+A connect handler function object:
+
+ struct connect_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a connect handler:
+
+ socket.async_connect(...,
+ [](const asio::error_code& ec)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a connect handler using
+`std::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ socket.async_connect(...,
+ std::bind(&my_class::connect_handler,
+ this, std::placeholders::_1));
+
+A non-static class member function adapted to a connect handler using
+`boost::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ socket.async_connect(...,
+ boost::bind(&my_class::connect_handler,
+ this, asio::placeholders::error));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ConstBufferSequence.qbk b/3rdparty/asio/src/doc/requirements/ConstBufferSequence.qbk
new file mode 100644
index 00000000000..1ff91ebf32a
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ConstBufferSequence.qbk
@@ -0,0 +1,55 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ConstBufferSequence Constant buffer sequence requirements]
+
+A ['constant buffer sequence] represents a set of memory regions that may be
+used as input to an operation, such as the `send` operation of a socket.
+
+A type `X` meets the `ConstBufferSequence` requirements if it satisfies the
+requirements of `Destructible` (C++Std [destructible]) and
+`CopyConstructible` (C++Std [copyconstructible]), as well as the additional
+requirements listed below.
+
+In the table below, `x` denotes a (possibly const) value of type `X`, and `u`
+denotes an identifier.
+
+[table ConstBufferSequence requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`asio::buffer_sequence_begin(x)`\n
+ `asio::buffer_sequence_end(x)`]
+ [An iterator type meeting the requirements for bidirectional iterators
+ (C++Std \[bidirectional.iterators\]) whose value type is convertible to
+ `const_buffer`.]
+ []
+ ]
+ [
+ [``
+ X u(x);
+ ``]
+ []
+ [post:\n
+ ``
+ equal(
+ asio::buffer_sequence_begin(x),
+ asio::buffer_sequence_end(x),
+ asio::buffer_sequence_begin(u),
+ asio::buffer_sequence_end(u),
+ [](const typename X::value_type& v1,
+ const typename X::value_type& v2)
+ {
+ const_buffer b1(v1);
+ const_buffer b2(v2);
+ return b1.data() == b2.data()
+ && b1.size() == b2.size();
+ })
+ ``]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/DynamicBuffer.qbk b/3rdparty/asio/src/doc/requirements/DynamicBuffer.qbk
new file mode 100644
index 00000000000..4e0cd880d51
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/DynamicBuffer.qbk
@@ -0,0 +1,93 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:DynamicBuffer Dynamic buffer requirements]
+
+A dynamic buffer encapsulates memory storage that may be automatically resized
+as required, where the memory is divided into an input sequence followed by an
+output sequence. These memory regions are internal to the dynamic buffer
+sequence, but direct access to the elements is provided to permit them to be
+efficiently used with I/O operations, such as the `send` or `receive`
+operations of a socket. Data written to the output sequence of a dynamic buffer
+sequence object is appended to the input sequence of the same object.
+
+A dynamic buffer type `X` shall satisfy the requirements of `MoveConstructible`
+(C++ Std, [moveconstructible]) types in addition to those listed below.
+
+In the table below, `X` denotes a dynamic buffer class, `x` denotes a
+value of type `X&`, `x1` denotes values of type `const X&`, and `n` denotes a
+value of type `size_t`, and `u` denotes an identifier.
+
+[table DynamicBuffer requirements
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`X::const_buffers_type`]
+ [type meeting [link asio.reference.ConstBufferSequence ConstBufferSequence]
+ requirements.]
+ [This type represents the memory associated with the input sequence.]
+ ]
+ [
+ [`X::mutable_buffers_type`]
+ [type meeting [link asio.reference.MutableBufferSequence MutableBufferSequence]
+ requirements.]
+ [This type represents the memory associated with the output sequence.]
+ ]
+ [
+ [`x1.size()`]
+ [`size_t`]
+ [Returns the size, in bytes, of the input sequence.]
+ ]
+ [
+ [`x1.max_size()`]
+ [`size_t`]
+ [Returns the permitted maximum of the sum of the sizes of the input
+ sequence and output sequence.]
+ ]
+ [
+ [`x1.capacity()`]
+ [`size_t`]
+ [Returns the maximum sum of the sizes of the input sequence and output
+ sequence that the dynamic buffer can hold without requiring reallocation.]
+ ]
+ [
+ [`x1.data()`]
+ [`X::const_buffers_type`]
+ [Returns a constant buffer sequence `u` that represents the memory
+ associated with the input sequence, and where `buffer_size(u) == size()`.]
+ ]
+ [
+ [`x.prepare(n)`]
+ [`X::mutable_buffers_type`]
+ [Requires: `size() + n <= max_size()`.\n
+ \n
+ Returns a mutable buffer sequence `u` representing the output sequence, and
+ where `buffer_size(u) == n`. The dynamic buffer reallocates memory as
+ required. All constant or mutable buffer sequences previously obtained
+ using `data()` or `prepare()` are invalidated.\n
+ \n
+ Throws: `length_error` if `size() + n > max_size()`.]
+ ]
+ [
+ [`x.commit(n)`]
+ []
+ [Appends `n` bytes from the start of the output sequence to the end of the
+ input sequence. The remainder of the output sequence is discarded. If `n`
+ is greater than the size of the output sequence, the entire output sequence
+ is appended to the input sequence. All constant or mutable buffer sequences
+ previously obtained using `data()` or `prepare()` are invalidated.]
+ ]
+ [
+ [`x.consume(n)`]
+ []
+ [Removes `n` bytes from beginning of the input sequence. If `n` is greater
+ than the size of the input sequence, the entire input sequence is removed.
+ All constant or mutable buffer sequences previously obtained using `data()`
+ or `prepare()` are invalidated.]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/Endpoint.qbk b/3rdparty/asio/src/doc/requirements/Endpoint.qbk
new file mode 100644
index 00000000000..4940dae4833
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/Endpoint.qbk
@@ -0,0 +1,94 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:Endpoint Endpoint requirements]
+
+A type `X` meets the `Endpoint` requirements if it satisfies the requirements
+of `Destructible` (C++Std [destructible]), `DefaultConstructible` (C++Std
+[defaultconstructible]), `CopyConstructible` (C++Std [copyconstructible]),
+and `CopyAssignable` (C++Std [copyassignable]), as well as the additional
+requirements listed below.
+
+In the table below, `a` denotes a (possibly const) value of type `X`, and `u`
+denotes an identifier.
+
+[table Endpoint requirements
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`X::protocol_type`]
+ [type meeting [link asio.reference.Protocol `Protocol`] requirements]
+ []
+ ]
+ [
+ [`a.protocol()`]
+ [`protocol_type`]
+ []
+ ]
+]
+
+In the table below, `a` denotes a (possibly const) value of type `X`, `b`
+denotes a value of type `X`, and `s` denotes a (possibly const) value of a type
+that is convertible to `size_t` and denotes a size in bytes.
+
+[table Endpoint requirements for extensible implementations
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`a.data()`]
+ [`const void*`]
+ [
+ Returns a pointer suitable for passing as the /address/ argument to
+ functions such as __POSIX__ __connect__, or as the /dest_addr/ argument
+ to functions such as __POSIX__ __sendto__. The implementation shall
+ perform a `static_cast` on the pointer to convert it to `const
+ sockaddr*`.
+ ]
+ ]
+ [
+ [`b.data()`]
+ [`void*`]
+ [
+ Returns a pointer suitable for passing as the /address/ argument to
+ functions such as __POSIX__ __accept__, __getpeername__, __getsockname__
+ and __recvfrom__. The implementation shall perform a `static_cast` on the
+ pointer to convert it to `sockaddr*`.
+ ]
+ ]
+ [
+ [`a.size()`]
+ [`size_t`]
+ [
+ Returns a value suitable for passing as the /address_len/ argument
+ to functions such as __POSIX__ __connect__, or as the /dest_len/ argument
+ to functions such as __POSIX__ __sendto__, after appropriate integer
+ conversion has been performed.
+ ]
+ ]
+ [
+ [`b.resize(s)`]
+ []
+ [
+ pre: `s >= 0`\n
+ post: `a.size() == s`\n
+ Passed the value contained in the /address_len/ argument to functions
+ such as __POSIX__ __accept__, __getpeername__, __getsockname__ and
+ __recvfrom__, after successful completion of the function. Permitted to
+ throw an exception if the protocol associated with the endpoint object
+ `a` does not support the specified size.
+ ]
+ ]
+ [
+ [`a.capacity()`]
+ [`size_t`]
+ [
+ Returns a value suitable for passing as the /address_len/ argument to
+ functions such as __POSIX__ __accept__, __getpeername__, __getsockname__
+ and __recvfrom__, after appropriate integer conversion has been performed.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/EndpointSequence.qbk b/3rdparty/asio/src/doc/requirements/EndpointSequence.qbk
new file mode 100644
index 00000000000..1e1648eb7a7
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/EndpointSequence.qbk
@@ -0,0 +1,30 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:EndpointSequence Endpoint sequence requirements]
+
+A type `X` meets the `EndpointSequence` requirements if it satisfies the
+requirements of `Destructible` (C++Std [destructible]) and `CopyConstructible`
+(C++Std [copyconstructible]), as well as the additional requirements listed
+below.
+
+In the table below, `x` denotes a (possibly const) value of type `X`.
+
+[table EndpointSequence requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`x.begin()`\n
+ `x.end()`]
+ [A type meeting the requirements for forward iterators
+ (C++Std \[forward.iterators\]) whose value type is convertible to
+ a type satisfying the [link asio.reference.Endpoint `Endpoint`]
+ requirements.]
+ [[half_open_range `x.begin()`,`x.end()`] is a valid range.]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ExecutionContext.qbk b/3rdparty/asio/src/doc/requirements/ExecutionContext.qbk
new file mode 100644
index 00000000000..94d1cd141da
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ExecutionContext.qbk
@@ -0,0 +1,36 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ExecutionContext Execution context requirements]
+
+A type `X` meets the `ExecutionContext` requirements if it is publicly and
+unambiguously derived from `execution_context`, and satisfies the additional
+requirements listed below.
+
+In the table below, `x` denotes a value of type `X`.
+
+[table ExecutionContext requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`X::executor_type`]
+ [type meeting [link asio.reference.Executor1 `Executor`] requirements]
+ []
+ ]
+ [
+ [`x.~X()`]
+ []
+ [Destroys all unexecuted function objects that were submitted via an
+ executor object that is associated with the execution context.]
+ ]
+ [
+ [`x.get_executor()`]
+ [`X::executor_type`]
+ [Returns an executor object that is associated with the execution context.]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/Executor.qbk b/3rdparty/asio/src/doc/requirements/Executor.qbk
new file mode 100644
index 00000000000..07548605730
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/Executor.qbk
@@ -0,0 +1,141 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:Executor1 Executor requirements]
+
+The library describes a standard set of requirements for ['executors]. A type
+meeting the `Executor` requirements embodies a set of rules for determining how
+submitted function objects are to be executed.
+
+A type `X` meets the `Executor` requirements if it satisfies the requirements of
+`CopyConstructible` (C++Std [copyconstructible]) and `Destructible` (C++Std
+[destructible]), as well as the additional requirements listed below.
+
+No constructor, comparison operator, copy operation, move operation, swap
+operation, or member functions `context`, `on_work_started`, and
+`on_work_finished` on these types shall exit via an exception.
+
+The executor copy constructor, comparison operators, and other member functions
+defined in these requirements shall not introduce data races as a result of
+concurrent calls to those functions from different threads.
+
+Let `ctx` be the execution context returned by the executor's `context()`
+member function. An executor becomes ['invalid] when the first call to
+`ctx.shutdown()` returns. The effect of calling `on_work_started`,
+`on_work_finished`, `dispatch`, `post`, or `defer` on an invalid executor is
+undefined. [inline_note The copy constructor, comparison operators, and
+`context()` member function continue to remain valid until `ctx` is destroyed.]
+
+In the table below, `x1` and `x2` denote (possibly const) values of type `X`,
+`mx1` denotes an xvalue of type `X`, `f` denotes a `MoveConstructible` (C++Std
+[moveconstructible]) function object callable with zero arguments, `a` denotes
+a (possibly const) value of type `A` meeting the `Allocator` requirements
+(C++Std [allocator.requirements]), and `u` denotes an identifier.
+
+[table Executor requirements
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`X u(x1);`]
+ []
+ [Shall not exit via an exception.\n
+ \n
+ post: `u == x1` and
+ `std::addressof(u.context()) == std::addressof(x1.context()).`]
+ ]
+ [
+ [`X u(mx1);`]
+ []
+ [Shall not exit via an exception.\n
+ \n
+ post: `u` equals the prior value of `mx1` and
+ `std::addressof(u.context())` equals the prior value of
+ `std::addressof(mx1.context())`.]
+ ]
+ [
+ [`x1 == x2`]
+ [`bool`]
+ [ Returns `true` only if `x1` and `x2` can be interchanged with identical
+ effects in any of the expressions defined in these type requirements.
+ [inline_note Returning `false` does not necessarily imply that the effects
+ are not identical.]\n
+ \n
+ `operator==` shall be reflexive, symmetric, and transitive, and shall not
+ exit via an exception.]
+ ]
+ [
+ [`x1 != x2`]
+ [`bool`]
+ [Same as `!(x1 == x2)`.]
+ ]
+ [
+ [`x1.context()`]
+ [`execution_context&`, or `E&` where `E` is a type that satifisfies the
+ [link asio.reference.ExecutionContext `ExecutionContext`] requirements.]
+ [Shall not exit via an exception.\n
+ \n
+ The comparison operators and member functions defined in these
+ requirements shall not alter the reference returned by this function.]
+ ]
+ [
+ [`x1.on_work_started()`]
+ []
+ [Shall not exit via an exception.]
+ ]
+ [
+ [`x1.on_work_finished()`]
+ []
+ [Shall not exit via an exception.\n
+ \n
+ Precondition: A preceding call `x2.on_work_started()` where `x1 == x2`.]
+ ]
+ [
+ [`x1.dispatch(std::move(f),a)`]
+ []
+ [Effects: Creates an object `f1` initialized with
+ [^['DECAY_COPY]]`(forward<Func>(f))` (C++Std \[thread.decaycopy\]) in the
+ current thread of execution . Calls `f1()` at most once. The executor may
+ block forward progress of the caller until `f1()` finishes execution.\n
+ \n
+ Executor implementations should use the supplied allocator to allocate any
+ memory required to store the function object. Prior to invoking the
+ function object, the executor shall deallocate any memory allocated.
+ [inline_note Executors defined in this Technical Specification always use
+ the supplied allocator unless otherwise specified.]\n
+ \n
+ Synchronization: The invocation of `dispatch` synchronizes with (C++Std
+ \[intro.multithread\]) the invocation of `f1`.]
+ ]
+ [
+ [`x1.post(std::move(f),a)`\n
+ `x1.defer(std::move(f),a)`]
+ []
+ [Effects: Creates an object `f1` initialized with
+ [^['DECAY_COPY]]`(forward<Func>(f))` in the current thread of execution.
+ Calls `f1()` at most once. The executor shall not block forward progress
+ of the caller pending completion of `f1()`.\n
+ \n
+ Executor implementations should use the supplied allocator to allocate any
+ memory required to store the function object. Prior to invoking the
+ function object, the executor shall deallocate any memory allocated.
+ [inline_note Executors defined in this Technical Specification always use
+ the supplied allocator unless otherwise specified.]\n
+ \n
+ Synchronization: The invocation of `post` or `defer` synchronizes with
+ (C++Std \[intro.multithread\]) the invocation of `f1`.\n
+ \n
+ [inline_note Although the requirements placed on `defer` are identical to
+ `post`, the use of `post` conveys a preference that the caller ['does not]
+ block the first step of [^f1]'s progress, whereas `defer` conveys a
+ preference that the caller ['does] block the first step of [^f1]. One use
+ of `defer` is to convey the intention of the caller that [^f1] is a
+ continuation of the current call context. The executor may use this
+ information to optimize or otherwise adjust the way in which `f1` is
+ invoked.]]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/GettableSerialPortOption.qbk b/3rdparty/asio/src/doc/requirements/GettableSerialPortOption.qbk
new file mode 100644
index 00000000000..8da158da1a4
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/GettableSerialPortOption.qbk
@@ -0,0 +1,33 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:GettableSerialPortOption Gettable serial port option requirements]
+
+In the table below, `X` denotes a serial port option class, `a` denotes a value
+of `X`, `ec` denotes a value of type `error_code`, and `s` denotes a value of
+implementation-defined type ['[^storage]] (where ['[^storage]] is the type
+`DCB` on Windows and `termios` on __POSIX__ platforms), and `u` denotes an
+identifier.
+
+[table GettableSerialPortOption requirements
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [
+ `const `['[^storage]]`& u = s;`\n
+ `a.load(u, ec);`
+ ]
+ [`error_code`]
+ [
+ Retrieves the value of the serial port option from the storage.\n
+ \n
+ If successful, sets `ec` such that `!ec` is true. If an error occurred,
+ sets `ec` such that `!!ec` is true. Returns `ec`.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/GettableSocketOption.qbk b/3rdparty/asio/src/doc/requirements/GettableSocketOption.qbk
new file mode 100644
index 00000000000..e859a54e599
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/GettableSocketOption.qbk
@@ -0,0 +1,67 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:GettableSocketOption Gettable socket option requirements]
+
+A type `X` meets the `GettableSocketOption` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a (possibly const) value of type `X`, `b`
+denotes a value of type `X`, `p` denotes a (possibly const) value that meets
+the [link asio.reference.Protocol `Protocol`] requirements, and `s` denotes a
+(possibly const) value of a type that is convertible to `size_t` and denotes a
+size in bytes.
+
+[table GettableSocketOption requirements for extensible implementations
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`a.level(p)`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /level/ argument to __POSIX__
+ __getsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.name(p)`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /option_name/ argument to
+ __POSIX__ __getsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`b.data(p)`]
+ [`void*`]
+ [
+ Returns a pointer suitable for passing as the /option_value/ argument to
+ __POSIX__ __getsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.size(p)`]
+ [`size_t`]
+ [
+ Returns a value suitable for passing as the /option_len/ argument to
+ __POSIX__ __getsockopt__ (or equivalent), after appropriate
+ integer conversion has been performed.
+ ]
+ ]
+ [
+ [`b.resize(p,s)`]
+ []
+ [
+ post: `b.size(p) == s`.\n
+ Passed the value contained in the /option_len/ argument to __POSIX__
+ __getsockopt__ (or equivalent) after successful completion of the
+ function. Permitted to throw an exception if the socket option object `b`
+ does not support the specified size.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/Handler.qbk b/3rdparty/asio/src/doc/requirements/Handler.qbk
new file mode 100644
index 00000000000..74dcd05494b
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/Handler.qbk
@@ -0,0 +1,64 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:Handler Handlers]
+
+A handler must meet the requirements of `CopyConstructible` types (C++ Std,
+20.1.3).
+
+In the table below, `X` denotes a handler class, `h` denotes a value of `X`,
+`p` denotes a pointer to a block of allocated memory of type `void*`, `s`
+denotes the size for a block of allocated memory, and `f` denotes a function
+object taking no arguments.
+
+[table Handler requirements
+ [[expression] [return type] [assertion/note\npre/post-conditions]]
+ [
+ [``
+ using asio::asio_handler_allocate;
+ asio_handler_allocate(s, &h);
+ ``]
+ [`void*`]
+ [
+ Returns a pointer to a block of memory of size `s`. The pointer must
+ satisfy the same alignment requirements as a pointer returned by
+ `::operator new()`. Throws `bad_alloc` on failure.\n\n The
+ `asio_handler_allocate()` function is located using argument-dependent
+ lookup. The function `asio::asio_handler_allocate()` serves as a
+ default if no user-supplied function is available.
+ ]
+ ]
+ [
+ [``
+ using asio::asio_handler_deallocate;
+ asio_handler_deallocate(p, s, &h);
+ ``]
+ []
+ [
+ Frees a block of memory associated with a pointer `p`, of at least size
+ `s`, that was previously allocated using `asio_handler_allocate()`.\n\n The
+ `asio_handler_deallocate()` function is located using argument-dependent
+ lookup. The function `asio::asio_handler_deallocate()` serves as a
+ default if no user-supplied function is available.
+ ]
+ ]
+ [
+ [``
+ using asio::asio_handler_invoke;
+ asio_handler_invoke(f, &h);
+ ``]
+ []
+ [
+ Causes the function object `f` to be executed as if by calling `f()`.\n\n
+ The `asio_handler_invoke()` function is located using argument-dependent
+ lookup. The function `asio::asio_handler_invoke()` serves as a
+ default if no user-supplied function is available.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/HandshakeHandler.qbk b/3rdparty/asio/src/doc/requirements/HandshakeHandler.qbk
new file mode 100644
index 00000000000..98891bfd87d
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/HandshakeHandler.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:HandshakeHandler SSL handshake handler requirements]
+
+A handshake handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a handshake handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as a handshake handler:
+
+ void handshake_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+
+A handshake handler function object:
+
+ struct handshake_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a handshake handler:
+
+ ssl_stream.async_handshake(...,
+ [](const asio::error_code& ec)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a handshake handler using
+`std::bind()`:
+
+ void my_class::handshake_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_handshake(...,
+ std::bind(&my_class::handshake_handler,
+ this, std::placeholders::_1));
+
+A non-static class member function adapted to a handshake handler using
+`boost::bind()`:
+
+ void my_class::handshake_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_handshake(...,
+ boost::bind(&my_class::handshake_handler,
+ this, asio::placeholders::error));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/InternetProtocol.qbk b/3rdparty/asio/src/doc/requirements/InternetProtocol.qbk
new file mode 100644
index 00000000000..70ab668e8b2
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/InternetProtocol.qbk
@@ -0,0 +1,47 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:InternetProtocol Internet protocol requirements]
+
+A type `X` meets the `InternetProtocol` requirements if it satisfies the
+requirements of [link asio.reference.AcceptableProtocol `AcceptableProtocol`],
+as well as the additional requirements listed below.
+
+In the table below, `a` denotes a (possibly const) value of type `X`, and `b`
+denotes a (possibly const) value of type `X`.
+
+[table InternetProtocol requirements
+ [[expression] [return type] [assertion/note\npre/post-conditions]]
+ [
+ [`X::resolver`]
+ [`ip::basic_resolver<X>`]
+ [The type of a resolver for the protocol.]
+ ]
+ [
+ [`X::v4()`]
+ [`X`]
+ [Returns an object representing the IP version 4 protocol.]
+ ]
+ [
+ [`X::v6()`]
+ [`X`]
+ [Returns an object representing the IP version 6 protocol.]
+ ]
+ [
+ [`a == b`]
+ [convertible to `bool`]
+ [Returns `true` if `a` and `b` represent the same IP protocol version,
+ otherwise `false`.]
+ ]
+ [
+ [`a != b`]
+ [convertible to `bool`]
+ [Returns `!(a == b)`.]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/IoControlCommand.qbk b/3rdparty/asio/src/doc/requirements/IoControlCommand.qbk
new file mode 100644
index 00000000000..8809335a4ee
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/IoControlCommand.qbk
@@ -0,0 +1,34 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:IoControlCommand I/O control command requirements]
+
+A type `X` meets the `IoControlCommand` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a (possibly const) value of type `X`, and `b`
+denotes a value of type `X`.
+
+[table IoControlCommand requirements for extensible implementations
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`a.name()`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /request/ argument to
+ __POSIX__ __ioctl__ (or equivalent).
+ ]
+ ]
+ [
+ [`b.data()`]
+ [`void*`]
+ [
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/IoObjectService.qbk b/3rdparty/asio/src/doc/requirements/IoObjectService.qbk
new file mode 100644
index 00000000000..3d3ccc0fb61
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/IoObjectService.qbk
@@ -0,0 +1,62 @@
+[/
+ / Copyright (c) 2003-2015 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)
+ /]
+
+[section:IoObjectService I/O object service requirements]
+
+An I/O object service must meet the requirements for a [link
+asio.reference.Service service], as well as the requirements listed
+below.
+
+In the table below, `X` denotes an I/O object service class, `a` and `ao` denote
+values of type `X`, `b` and `c` denote values of type `X::implementation_type`,
+and `u` denotes an identifier.
+
+[table IoObjectService requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`X::implementation_type`]
+ []
+ []
+ ]
+ [
+ [`X::implementation_type u;`]
+ []
+ [note: `X::implementation_type` has a public default constructor and
+ destructor.]
+ ]
+ [
+ [``
+ a.construct(b);
+ ``]
+ []
+ []
+ ]
+ [
+ [``
+ a.destroy(b);
+ ``]
+ []
+ [note: `destroy()` will only be called on a value that has previously been
+ initialised with `construct()` or `move_construct()`.]
+ ]
+ [
+ [``
+ a.move_construct(b, c);
+ ``]
+ []
+ [note: only required for I/O objects that support movability.]
+ ]
+ [
+ [``
+ a.move_assign(b, ao, c);
+ ``]
+ []
+ [note: only required for I/O objects that support movability.]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/IteratorConnectHandler.qbk b/3rdparty/asio/src/doc/requirements/IteratorConnectHandler.qbk
new file mode 100644
index 00000000000..db2aee42c28
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/IteratorConnectHandler.qbk
@@ -0,0 +1,81 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:IteratorConnectHandler Iterator connect handler requirements]
+
+An iterator connect handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of an iterator connect handler
+class should work correctly in the expression `h(ec, i)`, where `ec` is an
+lvalue of type `const error_code` and `i` is an lvalue of the type `Iterator`
+used in the corresponding `connect()` or async_connect()` function.
+
+[heading Examples]
+
+A free function as an iterator connect handler:
+
+ void connect_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::iterator iterator)
+ {
+ ...
+ }
+
+An iterator connect handler function object:
+
+ struct connect_handler
+ {
+ ...
+ template <typename Iterator>
+ void operator()(
+ const asio::error_code& ec,
+ Iterator iterator)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as an iterator connect handler:
+
+ asio::async_connect(...,
+ [](const asio::error_code& ec,
+ asio::ip::tcp::resolver::iterator iterator)
+ {
+ ...
+ });
+
+A non-static class member function adapted to an iterator connect handler using
+`std::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::iterator iterator)
+ {
+ ...
+ }
+ ...
+ asio::async_connect(...,
+ std::bind(&my_class::connect_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to an iterator connect handler using
+`boost::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::iterator iterator)
+ {
+ ...
+ }
+ ...
+ asio::async_connect(...,
+ boost::bind(&my_class::connect_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::iterator));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/MoveAcceptHandler.qbk b/3rdparty/asio/src/doc/requirements/MoveAcceptHandler.qbk
new file mode 100644
index 00000000000..d545497fde6
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/MoveAcceptHandler.qbk
@@ -0,0 +1,61 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:MoveAcceptHandler Move accept handler requirements]
+
+A move accept handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a move accept handler class
+should work correctly in the expression `h(ec, s)`, where `ec` is an lvalue of
+type `const error_code` and `s` is an lvalue of the nested type
+`Protocol::socket` for the type `Protocol` of the socket class template.
+
+[heading Examples]
+
+A free function as a move accept handler:
+
+ void accept_handler(
+ const asio::error_code& ec, asio::ip::tcp::socket s)
+ {
+ ...
+ }
+
+A move accept handler function object:
+
+ struct accept_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec, asio::ip::tcp::socket s)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a move accept handler:
+
+ acceptor.async_accept(...,
+ [](const asio::error_code& ec, asio::ip::tcp::socket s)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a move accept handler using
+`std::bind()`:
+
+ void my_class::accept_handler(
+ const asio::error_code& ec, asio::ip::tcp::socket socket)
+ {
+ ...
+ }
+ ...
+ asio::async_accept(...,
+ std::bind(&my_class::accept_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/MutableBufferSequence.qbk b/3rdparty/asio/src/doc/requirements/MutableBufferSequence.qbk
new file mode 100644
index 00000000000..7683a682ec6
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/MutableBufferSequence.qbk
@@ -0,0 +1,56 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:MutableBufferSequence Mutable buffer sequence requirements]
+
+A ['mutable buffer sequence] represents a set of memory regions that may be
+used to receive the output of an operation, such as the `receive` operation of
+a socket.
+
+A type `X` meets the `MutableBufferSequence` requirements if it satisfies the
+requirements of `Destructible` (C++Std [destructible]) and
+`CopyConstructible` (C++Std [copyconstructible]), as well as the additional
+requirements listed below.
+
+In the table below, `x` denotes a (possibly const) value of type `X`, and `u`
+denotes an identifier.
+
+[table MutableBufferSequence requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`asio::buffer_sequence_begin(x)`\n
+ `asio::buffer_sequence_end(x)`]
+ [An iterator type meeting the requirements for bidirectional iterators
+ (C++Std \[bidirectional.iterators\]) whose value type is convertible to
+ `mutable_buffer`.]
+ []
+ ]
+ [
+ [``
+ X u(x);
+ ``]
+ []
+ [post:\n
+ ``
+ equal(
+ asio::buffer_sequence_begin(x),
+ asio::buffer_sequence_end(x),
+ asio::buffer_sequence_begin(u),
+ asio::buffer_sequence_end(u),
+ [](const typename X::value_type& v1,
+ const typename X::value_type& v2)
+ {
+ mutable_buffer b1(v1);
+ mutable_buffer b2(v2);
+ return b1.data() == b2.data()
+ && b1.size() == b2.size();
+ })
+ ``]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ProtoAllocator.qbk b/3rdparty/asio/src/doc/requirements/ProtoAllocator.qbk
new file mode 100644
index 00000000000..2d318f2565f
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ProtoAllocator.qbk
@@ -0,0 +1,19 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ProtoAllocator Proto-allocator requirements]
+
+A type `A` meets the proto-allocator requirements if `A` is `CopyConstructible`
+(C++Std [copyconstructible]), `Destructible` (C++Std [destructible]), and
+`allocator_traits<A>::rebind_alloc<U>` meets the allocator requirements (C++Std
+[allocator.requirements]), where `U` is an object type. [inline_note For
+example, `std::allocator<void>` meets the proto-allocator requirements but not
+the allocator requirements.] No constructor, comparison operator, copy
+operation, move operation, or swap operation on these types shall exit via an
+exception.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/Protocol.qbk b/3rdparty/asio/src/doc/requirements/Protocol.qbk
new file mode 100644
index 00000000000..7a55d147fc1
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/Protocol.qbk
@@ -0,0 +1,54 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:Protocol Protocol requirements]
+
+A type `X` meets the `Protocol` requirements if it satisfies the requirements
+of `Destructible` (C++Std [destructible]), `CopyConstructible` (C++Std
+[copyconstructible]), and `CopyAssignable` (C++Std [copyassignable]), as well
+as the additional requirements listed below.
+
+[table Protocol requirements
+ [[expression] [return type] [assertion/note\npre/post-conditions]]
+ [
+ [`X::endpoint`]
+ [type meeting [link asio.reference.Endpoint endpoint] requirements]
+ []
+ ]
+]
+
+In the table below, `a` denotes a (possibly const) value of type `X`.
+
+[table Protocol requirements for extensible implementations
+ [[expression] [return type] [assertion/note\npre/post-conditions]]
+ [
+ [`a.family()`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /domain/ argument to
+ __POSIX__ __socket__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.type()`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /type/ argument to __POSIX__
+ __socket__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.protocol()`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /protocol/ argument to
+ __POSIX__ __socket__ (or equivalent).
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/RangeConnectHandler.qbk b/3rdparty/asio/src/doc/requirements/RangeConnectHandler.qbk
new file mode 100644
index 00000000000..4300af1003b
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/RangeConnectHandler.qbk
@@ -0,0 +1,82 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:RangeConnectHandler Range connect handler requirements]
+
+A range connect handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a range connect handler class
+should work correctly in the expression `h(ec, ep)`, where `ec` is an lvalue of
+type `const error_code` and `ep` is an lvalue of the type `Protocol::endpoint`
+for the `Protocol` type in the corresponding `connect()` or async_connect()`
+function.
+
+[heading Examples]
+
+A free function as a range connect handler:
+
+ void connect_handler(
+ const asio::error_code& ec,
+ const asio::ip::tcp::endpoint& endpoint)
+ {
+ ...
+ }
+
+A range connect handler function object:
+
+ struct connect_handler
+ {
+ ...
+ template <typename Range>
+ void operator()(
+ const asio::error_code& ec,
+ const asio::ip::tcp::endpoint& endpoint)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a range connect handler:
+
+ asio::async_connect(...,
+ [](const asio::error_code& ec,
+ const asio::ip::tcp::endpoint& endpoint)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a range connect handler using
+`std::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec,
+ const asio::ip::tcp::endpoint& endpoint)
+ {
+ ...
+ }
+ ...
+ asio::async_connect(...,
+ std::bind(&my_class::connect_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to a range connect handler using
+`boost::bind()`:
+
+ void my_class::connect_handler(
+ const asio::error_code& ec,
+ const asio::ip::tcp::endpoint& endpoint)
+ {
+ ...
+ }
+ ...
+ asio::async_connect(...,
+ boost::bind(&my_class::connect_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::endpoint));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ReadHandler.qbk b/3rdparty/asio/src/doc/requirements/ReadHandler.qbk
new file mode 100644
index 00000000000..373af8720e0
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ReadHandler.qbk
@@ -0,0 +1,79 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ReadHandler Read handler requirements]
+
+A read handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a read handler class
+should work correctly in the expression `h(ec, s)`, where `ec` is an lvalue of
+type `const error_code` and `s` is an lvalue of type `const size_t`.
+
+[heading Examples]
+
+A free function as a read handler:
+
+ void read_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+
+A read handler function object:
+
+ struct read_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a read handler:
+
+ socket.async_read(...
+ [](const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a read handler using
+`std::bind()`:
+
+ void my_class::read_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ socket.async_read(...,
+ std::bind(&my_class::read_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to a read handler using
+`boost::bind()`:
+
+ void my_class::read_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ socket.async_read(...,
+ boost::bind(&my_class::read_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ResolveHandler.qbk b/3rdparty/asio/src/doc/requirements/ResolveHandler.qbk
new file mode 100644
index 00000000000..0ba93855a75
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ResolveHandler.qbk
@@ -0,0 +1,82 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ResolveHandler Resolve handler requirements]
+
+A resolve handler must meet the requirements for a [link asio.reference.Handler
+handler]. A value `h` of a resolve handler class should work correctly in the
+expression `h(ec, r)`, where `ec` is an lvalue of type `const error_code` and
+`r` is an lvalue of type `const ip::basic_resolver_results<InternetProtocol>`.
+`InternetProtocol` is the template parameter of the [link
+asio.reference.ip__basic_resolver `ip::basic_resolver<>`] which is used to
+initiate the asynchronous operation.
+
+[heading Examples]
+
+A free function as a resolve handler:
+
+ void resolve_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::results_type results)
+ {
+ ...
+ }
+
+A resolve handler function object:
+
+ struct resolve_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::results_type results)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a resolve handler:
+
+ resolver.async_resolve(...,
+ [](const asio::error_code& ec,
+ asio::ip::tcp::resolver::results_type results)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a resolve handler using
+`std::bind()`:
+
+ void my_class::resolve_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::results_type results)
+ {
+ ...
+ }
+ ...
+ resolver.async_resolve(...,
+ std::bind(&my_class::resolve_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to a resolve handler using
+`boost::bind()`:
+
+ void my_class::resolve_handler(
+ const asio::error_code& ec,
+ asio::ip::tcp::resolver::results_type results)
+ {
+ ...
+ }
+ ...
+ resolver.async_resolve(...,
+ boost::bind(&my_class::resolve_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::results));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/Service.qbk b/3rdparty/asio/src/doc/requirements/Service.qbk
new file mode 100644
index 00000000000..24a1ae584e4
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/Service.qbk
@@ -0,0 +1,40 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:Service Service requirements]
+
+A class is a ['service] if it is publicly and unambiguously derived from
+`execution_context::service`, or if it is publicly and unambiguously derived
+from another service. For a service `S`, `S::key_type` shall be valid and
+denote a type (C++Std [temp.deduct]), `is_base_of_v<typename S::key_type, S>`
+shall be `true`, and `S` shall satisfy the `Destructible` requirements (C++Std
+[destructible]).
+
+The first parameter of all service constructors shall be an lvalue reference to
+`execution_context`. This parameter denotes the `execution_context` object that
+represents a set of services, of which the service object will be a member.
+[inline_note These constructors may be called by the `make_service` function.]
+
+A service shall provide an explicit constructor with a single parameter of
+lvalue reference to `execution_context`. [inline_note This constructor may be
+called by the `use_service` function.]
+
+ class my_service : public execution_context::service
+ {
+ public:
+ typedef my_service key_type;
+ explicit my_service(execution_context& ctx);
+ my_service(execution_context& ctx, int some_value);
+ private:
+ virtual void shutdown() noexcept override;
+ ...
+ };
+
+A service's `shutdown` member function shall destroy all copies of user-defined
+function objects that are held by the service.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SettableSerialPortOption.qbk b/3rdparty/asio/src/doc/requirements/SettableSerialPortOption.qbk
new file mode 100644
index 00000000000..5cbe5f13e5c
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SettableSerialPortOption.qbk
@@ -0,0 +1,33 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SettableSerialPortOption Settable serial port option requirements]
+
+In the table below, `X` denotes a serial port option class, `a` denotes a value
+of `X`, `ec` denotes a value of type `error_code`, and `s` denotes a value of
+implementation-defined type ['[^storage]] (where ['[^storage]] is the type
+`DCB` on Windows and `termios` on __POSIX__ platforms), and `u` denotes an
+identifier.
+
+[table SettableSerialPortOption requirements
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [
+ `const X& u = a;`\n
+ `u.store(s, ec);`
+ ]
+ [`error_code`]
+ [
+ Saves the value of the serial port option to the storage.\n
+ \n
+ If successful, sets `ec` such that `!ec` is true. If an error occurred,
+ sets `ec` such that `!!ec` is true. Returns `ec`.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SettableSocketOption.qbk b/3rdparty/asio/src/doc/requirements/SettableSocketOption.qbk
new file mode 100644
index 00000000000..162c0a96325
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SettableSocketOption.qbk
@@ -0,0 +1,54 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SettableSocketOption Settable socket option requirements]
+
+A type `X` meets the `SettableSocketOption` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a (possibly const) value of type `X`, `p`
+denotes a (possibly const) value that meets the [link asio.reference.Protocol
+`Protocol`] requirements, and `u` denotes an identifier.
+
+[table SettableSocketOption requirements for extensible implementations
+ [[expression] [type] [assertion/note\npre/post-conditions]]
+ [
+ [`a.level(p)`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /level/ argument to __POSIX__
+ __setsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.name(p)`]
+ [`int`]
+ [
+ Returns a value suitable for passing as the /option_name/ argument to
+ __POSIX__ __setsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.data(p)`]
+ [`const void*`]
+ [
+ Returns a pointer suitable for passing as the /option_value/ argument to
+ __POSIX__ __setsockopt__ (or equivalent).
+ ]
+ ]
+ [
+ [`a.size(p)`]
+ [`size_t`]
+ [
+ Returns a value suitable for passing as the /option_len/ argument to
+ __POSIX__ __setsockopt__ (or equivalent), after appropriate integer
+ conversion has been performed.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/ShutdownHandler.qbk b/3rdparty/asio/src/doc/requirements/ShutdownHandler.qbk
new file mode 100644
index 00000000000..601c625cb11
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/ShutdownHandler.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:ShutdownHandler SSL shutdown handler requirements]
+
+A shutdown handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a shutdown handler
+class should work correctly in the expression `h(ec)`, where `ec` is an lvalue
+of type `const error_code`.
+
+[heading Examples]
+
+A free function as a shutdown handler:
+
+ void shutdown_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+
+A shutdown handler function object:
+
+ struct shutdown_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a shutdown handler:
+
+ ssl_stream.async_shutdown(...,
+ [](const asio::error_code& ec)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a shutdown handler using
+`std::bind()`:
+
+ void my_class::shutdown_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_shutdown(
+ std::bind(&my_class::shutdown_handler,
+ this, std::placeholders::_1));
+
+A non-static class member function adapted to a shutdown handler using
+`boost::bind()`:
+
+ void my_class::shutdown_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ ssl_stream.async_shutdown(
+ boost::bind(&my_class::shutdown_handler,
+ this, asio::placeholders::error));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SignalHandler.qbk b/3rdparty/asio/src/doc/requirements/SignalHandler.qbk
new file mode 100644
index 00000000000..cfd806a8448
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SignalHandler.qbk
@@ -0,0 +1,79 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SignalHandler Signal handler requirements]
+
+A signal handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a signal handler class
+should work correctly in the expression `h(ec, n)`, where `ec` is an lvalue of
+type `const error_code` and `n` is an lvalue of type `const int`.
+
+[heading Examples]
+
+A free function as a signal handler:
+
+ void signal_handler(
+ const asio::error_code& ec,
+ int signal_number)
+ {
+ ...
+ }
+
+A signal handler function object:
+
+ struct signal_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec,
+ int signal_number)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a signal handler:
+
+ my_signal_set.async_wait(
+ [](const asio::error_code& ec,
+ int signal_number)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a signal handler using
+`std::bind()`:
+
+ void my_class::signal_handler(
+ const asio::error_code& ec,
+ int signal_number)
+ {
+ ...
+ }
+ ...
+ my_signal_set.async_wait(
+ std::bind(&my_class::signal_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to a signal handler using
+`boost::bind()`:
+
+ void my_class::signal_handler(
+ const asio::error_code& ec,
+ int signal_number)
+ {
+ ...
+ }
+ ...
+ my_signal_set.async_wait(
+ boost::bind(&my_class::signal_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::signal_number));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SyncRandomAccessReadDevice.qbk b/3rdparty/asio/src/doc/requirements/SyncRandomAccessReadDevice.qbk
new file mode 100644
index 00000000000..4e960b0a55e
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SyncRandomAccessReadDevice.qbk
@@ -0,0 +1,49 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SyncRandomAccessReadDevice Buffer-oriented synchronous random-access
+read device requirements]
+
+In the table below, `a` denotes a synchronous random-access read device object,
+`o` denotes an offset of type `boost::uint64_t`, `mb` denotes an object
+satisfying [link asio.reference.MutableBufferSequence mutable buffer sequence]
+requirements, and `ec` denotes an object of type `error_code`.
+
+[table Buffer-oriented synchronous random-access read device requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.read_some_at(o, mb);`]
+ [`size_t`]
+ [Equivalent to:
+ ``
+ error_code ec;
+ size_t s = a.read_some_at(o, mb, ec);
+ if (ec) throw system_error(ec);
+ return s;
+ ``]
+ ]
+ [
+ [`a.read_some_at(o, mb, ec);`]
+ [`size_t`]
+ [
+ Reads one or more bytes of data from the device `a` at offset `o`.\n
+ \n
+ The mutable buffer sequence `mb` specifies memory where the data should
+ be placed. The `read_some_at` operation shall always fill a buffer in the
+ sequence completely before proceeding to the next.\n
+ \n
+ If successful, returns the number of bytes read and sets `ec` such that
+ `!ec` is true. If an error occurred, returns `0` and sets `ec` such that
+ `!!ec` is true.\n
+ \n
+ If the total size of all buffers in the sequence `mb` is `0`, the
+ function shall return `0` immediately.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SyncRandomAccessWriteDevice.qbk b/3rdparty/asio/src/doc/requirements/SyncRandomAccessWriteDevice.qbk
new file mode 100644
index 00000000000..c7a2686f17b
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SyncRandomAccessWriteDevice.qbk
@@ -0,0 +1,49 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SyncRandomAccessWriteDevice Buffer-oriented synchronous random-access
+write device requirements]
+
+In the table below, `a` denotes a synchronous random-access write device
+object, `o` denotes an offset of type `boost::uint64_t`, `cb` denotes an object
+satisfying [link asio.reference.ConstBufferSequence constant buffer sequence]
+requirements, and `ec` denotes an object of type `error_code`.
+
+[table Buffer-oriented synchronous random-access write device requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.write_some_at(o, cb);`]
+ [`size_t`]
+ [Equivalent to:
+ ``
+ error_code ec;
+ size_t s = a.write_some(o, cb, ec);
+ if (ec) throw system_error(ec);
+ return s;
+ ``]
+ ]
+ [
+ [`a.write_some_at(o, cb, ec);`]
+ [`size_t`]
+ [
+ Writes one or more bytes of data to the device `a` at offset `o`.\n
+ \n
+ The constant buffer sequence `cb` specifies memory where the data to be
+ written is located. The `write_some_at` operation shall always write a
+ buffer in the sequence completely before proceeding to the next.\n
+ \n
+ If successful, returns the number of bytes written and sets `ec` such
+ that `!ec` is true. If an error occurred, returns `0` and sets `ec` such
+ that `!!ec` is true.\n
+ \n
+ If the total size of all buffers in the sequence `cb` is `0`, the
+ function shall return `0` immediately.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SyncReadStream.qbk b/3rdparty/asio/src/doc/requirements/SyncReadStream.qbk
new file mode 100644
index 00000000000..48d3c23816d
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SyncReadStream.qbk
@@ -0,0 +1,41 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SyncReadStream Buffer-oriented synchronous read stream requirements]
+
+A type `X` meets the `SyncReadStream` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a value of type `X`, `mb` denotes a (possibly
+const) value satisfying the [link asio.reference.MutableBufferSequence
+`MutableBufferSequence`] requirements, and `ec` denotes an object of type
+`error_code`.
+
+[table SyncReadStream requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.read_some(mb)`\n
+ `a.read_some(mb,ec)`]
+ [`size_t`]
+ [
+ Meets the requirements for a [link asio.reference.read_write_operations
+ read operation].\n
+ \n
+ If `buffer_size(mb) > 0`, reads one or more bytes of data from the stream
+ `a` into the buffer sequence `mb`. If successful, sets `ec` such that
+ `!ec` is `true`, and returns the number of bytes read. If an error
+ occurred, sets `ec` such that `!!ec` is `true`, and returns 0. If all
+ data has been read from the stream, and the stream performed an orderly
+ shutdown, sets `ec` to `stream_errc::eof` and returns 0.\n
+ \n
+ If `buffer_size(mb) == 0`, the operation shall not block. Sets `ec` such
+ that `!ec` is `true`, and returns 0.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/SyncWriteStream.qbk b/3rdparty/asio/src/doc/requirements/SyncWriteStream.qbk
new file mode 100644
index 00000000000..713050c7552
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/SyncWriteStream.qbk
@@ -0,0 +1,39 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:SyncWriteStream Buffer-oriented synchronous write stream requirements]
+
+A type `X` meets the `SyncWriteStream` requirements if it satisfies the
+requirements listed below.
+
+In the table below, `a` denotes a value of type `X`, `cb` denotes a (possibly
+const) value satisfying the [link asio.reference.ConstBufferSequence
+`ConstBufferSequence`] requirements, and `ec` denotes an object of type
+`error_code`.
+
+[table SyncWriteStream requirements
+ [[operation] [type] [semantics, pre/post-conditions]]
+ [
+ [`a.write_some(cb)`\n
+ `a.write_some(cb,ec)`]
+ [`size_t`]
+ [
+ Meets the requirements for a [link asio.reference.read_write_operations
+ write operation].\n
+ \n
+ If `buffer_size(cb) > 0`, writes one or more bytes of data to the stream
+ `a` from the buffer sequence `cb`. If successful, sets `ec` such that
+ `!ec` is `true`, and returns the number of bytes written. If an error
+ occurred, sets `ec` such that `!!ec` is `true`, and returns 0.\n
+ \n
+ If `buffer_size(cb) == 0`, the operation shall not block. Sets `ec` such
+ that `!ec` is `true`, and returns 0.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/TimeTraits.qbk b/3rdparty/asio/src/doc/requirements/TimeTraits.qbk
new file mode 100644
index 00000000000..edd01b8fd30
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/TimeTraits.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:TimeTraits Time traits requirements]
+
+In the table below, `X` denotes a time traits class for time type `Time`, `t`,
+`t1`, and `t2` denote values of type `Time`, and `d` denotes a value of type
+`X::duration_type`.
+
+[table TimeTraits requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`X::time_type`]
+ [`Time`]
+ [
+ Represents an absolute time. Must support default construction, and meet
+ the requirements for `CopyConstructible` and `Assignable`.
+ ]
+ ]
+ [
+ [`X::duration_type`]
+ []
+ [
+ Represents the difference between two absolute times. Must support
+ default construction, and meet the requirements for `CopyConstructible`
+ and `Assignable`. A duration can be positive, negative, or zero.
+ ]
+ ]
+ [
+ [`X::now();`]
+ [`time_type`]
+ [
+ Returns the current time.
+ ]
+ ]
+ [
+ [`X::add(t, d);`]
+ [`time_type`]
+ [
+ Returns a new absolute time resulting from adding the duration `d` to the
+ absolute time `t`.
+ ]
+ ]
+ [
+ [`X::subtract(t1, t2);`]
+ [`duration_type`]
+ [
+ Returns the duration resulting from subtracting `t2` from `t1`.
+ ]
+ ]
+ [
+ [`X::less_than(t1, t2);`]
+ [`bool`]
+ [
+ Returns whether `t1` is to be treated as less than `t2`.
+ ]
+ ]
+ [
+ [`X::to_posix_duration(d);`]
+ [`date_time::time_duration_type`]
+ [
+ Returns the `date_time::time_duration_type` value that most closely
+ represents the duration `d`.
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/WaitHandler.qbk b/3rdparty/asio/src/doc/requirements/WaitHandler.qbk
new file mode 100644
index 00000000000..a7135f07369
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/WaitHandler.qbk
@@ -0,0 +1,72 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:WaitHandler Wait handler requirements]
+
+A wait handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a wait handler class
+should work correctly in the expression `h(ec)`, where `ec` is an lvalue of
+type `const error_code`.
+
+[heading Examples]
+
+A free function as a wait handler:
+
+ void wait_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+
+A wait handler function object:
+
+ struct wait_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a wait handler:
+
+ socket.async_wait(...,
+ [](const asio::error_code& ec)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a wait handler using
+`std::bind()`:
+
+ void my_class::wait_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ socket.async_wait(...,
+ std::bind(&my_class::wait_handler,
+ this, std::placeholders::_1));
+
+A non-static class member function adapted to a wait handler using
+`boost::bind()`:
+
+ void my_class::wait_handler(
+ const asio::error_code& ec)
+ {
+ ...
+ }
+ ...
+ socket.async_wait(...,
+ boost::bind(&my_class::wait_handler,
+ this, asio::placeholders::error));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/WaitTraits.qbk b/3rdparty/asio/src/doc/requirements/WaitTraits.qbk
new file mode 100644
index 00000000000..13eb7482879
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/WaitTraits.qbk
@@ -0,0 +1,52 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:WaitTraits Wait traits requirements]
+
+The `basic_waitable_timer` template uses wait traits to allow programs to
+customize `wait` and `async_wait` behavior.
+[inline_note Possible uses of wait traits include:\n
+[mdash] To enable timers based on non-realtime clocks.\n
+[mdash] Determining how quickly wallclock-based timers respond to system time
+changes.\n
+[mdash] Correcting for errors or rounding timeouts to boundaries.\n
+[mdash] Preventing duration overflow. That is, a program may set a timer's
+expiry `e` to be `Clock::max()` (meaning never reached) or `Clock::min()`
+(meaning always in the past). As a result, computing the duration until timer
+expiry as `e - Clock::now()` may cause overflow.]
+
+For a type `Clock` meeting the `Clock` requirements (C++Std
+[time.clock.req]), a type `X` meets the `WaitTraits` requirements if it
+satisfies the requirements listed below.
+
+In the table below, `t` denotes a (possibly const) value of type
+`Clock::time_point`; and `d` denotes a (possibly const) value of type
+`Clock::duration`.
+
+[table WaitTraits requirements
+ [[expression] [return type] [assertion/note\npre/post-condition]]
+ [
+ [`X::to_wait_duration(d)`]
+ [`Clock::duration`]
+ [
+ Returns a `Clock::duration` value to be used in a `wait` or `async_wait`
+ operation. [inline_note The return value is typically representative of
+ the duration `d`.]
+ ]
+ ]
+ [
+ [`X::to_wait_duration(t)`]
+ [`Clock::duration`]
+ [
+ Returns a `Clock::duration` value to be used in a `wait` or `async_wait`
+ operation. [inline_note The return value is typically representative of
+ the duration from `Clock::now()` until the time point `t`.]
+ ]
+ ]
+]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/WriteHandler.qbk b/3rdparty/asio/src/doc/requirements/WriteHandler.qbk
new file mode 100644
index 00000000000..29987ad8dd6
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/WriteHandler.qbk
@@ -0,0 +1,79 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:WriteHandler Write handler requirements]
+
+A write handler must meet the requirements for a [link
+asio.reference.Handler handler]. A value `h` of a write handler class
+should work correctly in the expression `h(ec, s)`, where `ec` is an lvalue of
+type `const error_code` and `s` is an lvalue of type `const size_t`.
+
+[heading Examples]
+
+A free function as a write handler:
+
+ void write_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+
+A write handler function object:
+
+ struct write_handler
+ {
+ ...
+ void operator()(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ };
+
+A lambda as a write handler:
+
+ socket.async_write(...
+ [](const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ });
+
+A non-static class member function adapted to a write handler using
+`std::bind()`:
+
+ void my_class::write_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ socket.async_write(...,
+ std::bind(&my_class::write_handler,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+
+A non-static class member function adapted to a write handler using
+`boost::bind()`:
+
+ void my_class::write_handler(
+ const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ ...
+ }
+ ...
+ socket.async_write(...,
+ boost::bind(&my_class::write_handler,
+ this, asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/asynchronous_operations.qbk b/3rdparty/asio/src/doc/requirements/asynchronous_operations.qbk
new file mode 100644
index 00000000000..40ccccf4c55
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/asynchronous_operations.qbk
@@ -0,0 +1,281 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:asynchronous_operations Requirements on asynchronous operations]
+
+This section uses the names `Alloc1`, `Alloc2`, `alloc1`, `alloc2`, `Args`,
+`CompletionHandler`, `completion_handler`, `Executor1`, `Executor2`, `ex1`,
+`ex2`, `f`, [^['i]], [^['N]], `Signature`, `token`, [^T[sub ['i]]], [^t[sub
+['i]]], `work1`, and `work2` as placeholders for specifying the requirements
+below.
+
+[section General asynchronous operation concepts]
+
+An ['initiating function] is a function which may be called to start an
+asynchronous operation. A ['completion handler] is a function object that will
+be invoked, at most once, with the result of the asynchronous operation.
+
+The lifecycle of an asynchronous operation is comprised of the following events
+and phases:
+
+[mdash] Event 1: The asynchronous operation is started by a call to the
+initiating function.
+
+[mdash] Phase 1: The asynchronous operation is now ['outstanding].
+
+[mdash] Event 2: The externally observable side effects of the asynchronous
+operation, if any, are fully established. The completion handler is submitted
+to an executor.
+
+[mdash] Phase 2: The asynchronous operation is now ['completed].
+
+[mdash] Event 3: The completion handler is called with the result of the
+asynchronous operation.
+
+In this library, all functions with the prefix `async_` are initiating
+functions.
+
+[endsect]
+
+[section:completion_token Completion tokens and handlers]
+
+Initiating functions:
+
+[mdash] are function templates with template parameter `CompletionToken`;
+
+[mdash] accept, as the final parameter, a ['completion token] object `token`
+of type `CompletionToken`;
+
+[mdash] specify a ['completion signature], which is a call signature (C++Std
+[func.def]) `Signature` that determines the arguments to the completion
+handler.
+
+An initiating function determines the type `CompletionHandler` of its
+completion handler function object by performing `typename
+async_result<decay_t<CompletionToken>, Signature>::completion_handler_type`.
+The completion handler object `completion_handler` is initialized with
+`forward<CompletionToken>(token)`. [inline_note No other requirements are
+placed on the type `CompletionToken`.]
+
+The type `CompletionHandler` must satisfy the requirements of `Destructible`
+(C++Std [destructible]) and `MoveConstructible` (C++Std
+[moveconstructible]), and be callable with the specified call signature.
+
+In this library, all initiating functions specify a ['Completion signature]
+element that defines the call signature `Signature`. The ['Completion
+signature] elements in this Technical Specification have named parameters, and
+the results of an asynchronous operation are specified in terms of these names.
+
+[endsect]
+
+[section Automatic deduction of initiating function return type]
+
+The return type of an initiating function is `typename
+async_result<decay_t<CompletionToken>, Signature>::return_type`.
+
+For the sake of exposition, this library sometimes annotates functions with a
+return type ['[^DEDUCED]]. For every function declaration that returns
+['[^DEDUCED]], the meaning is equivalent to specifying the return type as
+`typename async_result<decay_t<CompletionToken>, Signature>::return_type`.
+
+[endsect]
+
+[section Production of initiating function return value]
+
+An initiating function produces its return type as follows:
+
+[mdash] constructing an object `result` of type
+`async_result<decay_t<CompletionToken>, Signature>`, initialized as
+`result(completion_handler)`; and
+
+[mdash] using `result.get()` as the operand of the return statement.
+
+\[['Example:] Given an asynchronous operation with ['Completion signature]
+`void(R1 r1, R2 r2)`, an initiating function meeting these requirements may be
+implemented as follows:
+
+ template<class CompletionToken>
+ auto async_xyz(T1 t1, T2 t2, CompletionToken&& token)
+ {
+ typename async_result<decay_t<CompletionToken>, void(R1, R2)>::completion_handler_type
+ completion_handler(forward<CompletionToken>(token));
+
+ async_result<decay_t<CompletionToken>, void(R1, R2)> result(completion_handler);
+
+ // initiate the operation and cause completion_handler to be invoked with
+ // the result
+
+ return result.get();
+ }
+
+For convenience, initiating functions may be implemented using the
+`async_completion` template:
+
+ template<class CompletionToken>
+ auto async_xyz(T1 t1, T2 t2, CompletionToken&& token)
+ {
+ async_completion<CompletionToken, void(R1, R2)> init(token);
+
+ // initiate the operation and cause init.completion_handler to be invoked
+ // with the result
+
+ return init.result.get();
+ }
+
+'''&mdash;'''['end example]\]
+
+[endsect]
+
+[section Lifetime of initiating function arguments]
+
+Unless otherwise specified, the lifetime of arguments to initiating functions
+shall be treated as follows:
+
+[mdash] If the parameter has a pointer type or has a type of lvalue reference
+to non-const, the implementation may assume the validity of the pointee or
+referent, respectively, until the completion handler is invoked. [inline_note
+In other words, the program must guarantee the validity of the argument until
+the completion handler is invoked.]
+
+[mdash] Otherwise, the implementation must not assume the validity of the
+argument after the initiating function completes. [inline_note In other words,
+the program is not required to guarantee the validity of the argument after the
+initiating function completes.] The implementation may make copies of the
+argument, and all copies shall be destroyed no later than immediately after
+invocation of the completion handler.
+
+[endsect]
+
+[section Non-blocking requirements on initiating functions]
+
+An initiating function shall not block (C++Std [defns.block]) the calling
+thread pending completion of the outstanding operation.
+
+[std_note Initiating functions may still block the calling thread for other
+reasons. For example, an initiating function may lock a mutex in order to
+synchronize access to shared data.]
+
+[endsect]
+
+[section Associated executor]
+
+Certain objects that participate in asynchronous operations have an
+['associated executor]. These are obtained as specified below.
+
+[endsect]
+
+[section I/O executor]
+
+An asynchronous operation has an associated executor satisfying the [link
+asio.reference.Executor1 `Executor`] requirements. If not otherwise specified by
+the asynchronous operation, this associated executor is an object of type
+`system_executor`.
+
+All asynchronous operations in this library have an associated executor object
+that is determined as follows:
+
+[mdash] If the initiating function is a member function, the associated
+executor is that returned by the `get_executor` member function on the same
+object.
+
+[mdash] If the initiating function is not a member function, the associated
+executor is that returned by the `get_executor` member function of the first
+argument to the initiating function.
+
+Let `Executor1` be the type of the associated executor. Let `ex1` be a value of
+type `Executor1`, representing the associated executor object obtained as
+described above.
+
+[endsect]
+
+[section Completion handler executor]
+
+A completion handler object of type `CompletionHandler` has an associated
+executor of type `Executor2` satisfying the [link asio.reference.Executor1
+Executor requirements]. The type `Executor2` is
+`associated_executor_t<CompletionHandler, Executor1>`. Let `ex2` be a value of
+type `Executor2` obtained by performing
+`get_associated_executor(completion_handler, ex1)`.
+
+[endsect]
+
+[section Outstanding work]
+
+Until the asynchronous operation has completed, the asynchronous operation
+shall maintain:
+
+[mdash] an object `work1` of type `executor_work_guard<Executor1>`, initialized
+as `work1(ex1)`, and where `work1.owns_work() == true`; and
+
+[mdash] an object `work2` of type `executor_work_guard<Executor2>`, initialized
+as `work2(ex2)`, and where `work2.owns_work() == true`.
+
+[endsect]
+
+[section Allocation of intermediate storage]
+
+Asynchronous operations may allocate memory. [inline_note Such as a data
+structure to store copies of the `completion_handler` object and the initiating
+function's arguments.]
+
+Let `Alloc1` be a type, satisfying the [link asio.reference.ProtoAllocator
+`ProtoAllocator`] requirements, that represents the asynchronous operation's
+default allocation strategy. [inline_note Typically `std::allocator<void>`.]
+Let `alloc1` be a value of type `Alloc1`.
+
+A completion handler object of type `CompletionHandler` has an associated
+allocator object `alloc2` of type `Alloc2` satisfying the [link
+asio.reference.ProtoAllocator `ProtoAllocator`] requirements. The type `Alloc2`
+is `associated_allocator_t<CompletionHandler, Alloc1>`. Let `alloc2` be a value
+of type `Alloc2` obtained by performing
+`get_associated_allocator(completion_handler, alloc1)`.
+
+The asynchronous operations defined in this library:
+
+[mdash] If required, allocate memory using only the completion handler's
+associated allocator.
+
+[mdash] Prior to completion handler execution, deallocate any memory allocated
+using the completion handler's associated allocator.
+
+[std_note The implementation may perform operating system or underlying API
+calls that perform memory allocations not using the associated allocator.
+Invocations of the allocator functions may not introduce data races (See C++Std
+\[res.on.data.races\]).]
+
+[endsect]
+
+[section Execution of completion handler on completion of asynchronous operation]
+
+Let `Args...` be the argument types of the completion signature `Signature` and
+let [^['N]] be `sizeof...(Args)`. Let [^['i]] be in the range [half_open_range
+`0`,[^['N]]]. Let [^T[sub ['i]]] be the [^['i]]th type in `Args...` and let
+[^t[sub ['i]]] be the [^['i]]th completion handler argument associated with
+[^T[sub ['i]]].
+
+Let `f` be a function object, callable as `f()`, that invokes
+`completion_handler` as if by [^completion_handler(forward<T[sub ['0]]>(t[sub
+['0]]), ..., forward<T[sub ['N-1]]>(t[sub ['N-1]]))].
+
+If an asynchonous operation completes immediately (that is, within the thread
+of execution calling the initiating function, and before the initiating
+function returns), the completion handler shall be submitted for execution as
+if by performing `ex2.post(std::move(f), alloc2)`. Otherwise, the completion
+handler shall be submitted for execution as if by performing
+`ex2.dispatch(std::move(f), alloc2)`.
+
+[endsect]
+
+[section Completion handlers and exceptions]
+
+Completion handlers are permitted to throw exceptions. The effect of any
+exception propagated from the execution of a completion handler is determined
+by the executor which is executing the completion handler.
+
+[endsect]
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/asynchronous_socket_operations.qbk b/3rdparty/asio/src/doc/requirements/asynchronous_socket_operations.qbk
new file mode 100644
index 00000000000..c0555286176
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/asynchronous_socket_operations.qbk
@@ -0,0 +1,39 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:asynchronous_socket_operations Requirements on asynchronous socket operations]
+
+In this library, ['asynchronous socket operations] are those member functions
+having prefix `async_`.
+
+For an object `s`, a program may initiate asynchronous socket operations such
+that there are multiple simultaneously outstanding asynchronous operations.
+
+When there are multiple outstanding asynchronous [link
+asio.reference.read_write_operations read operations] on `s`:
+
+[mdash] having no argument `flags` of type `socket_base::message_flags`, or
+
+[mdash] having an argument `flags` of type `socket_base::message_flags` but
+where `(flags & socket_base::message_out_of_band) == 0`
+
+then the `buffers` are filled in the order in which these operations were
+issued. The order of invocation of the completion handlers for these operations
+is unspecified.
+
+When there are multiple outstanding asynchronous [link
+asio.reference.read_write_operations read operations] on `s` having an argument
+`flags` of type `socket_base::message_flags` where `(flags &
+socket_base::message_out_of_band) != 0` then the `buffers` are filled in the
+order in which these operations were issued.
+
+When there are multiple outstanding asynchronous [link
+asio.reference.read_write_operations write operations] on `s`, the `buffers`
+are transmitted in the order in which these operations were issued. The order
+of invocation of the completion handlers for these operations is unspecified.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/read_write_operations.qbk b/3rdparty/asio/src/doc/requirements/read_write_operations.qbk
new file mode 100644
index 00000000000..d7185a9beaf
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/read_write_operations.qbk
@@ -0,0 +1,34 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:read_write_operations Requirements on read and write operations]
+
+A ['read operation] is an operation that reads data into a mutable buffer
+sequence argument of a type meeting [link asio.reference.MutableBufferSequence
+`MutableBufferSequence`] requirements. The mutable buffer sequence specifies
+memory where the data should be placed. A read operation shall always fill a
+buffer in the sequence completely before proceeding to the next.
+
+A ['write operation] is an operation that writes data from a constant buffer
+sequence argument of a type meeting [link asio.reference.ConstBufferSequence
+`ConstBufferSequence`] requirements. The constant buffer sequence specifies
+memory where the data to be written is located. A write operation shall always
+write a buffer in the sequence completely before proceeding to the next.
+
+If a read or write operation is also an [link
+asio.reference.asynchronous_operations asynchronous operation], the operation
+shall maintain one or more copies of the buffer sequence until such time as the
+operation no longer requires access to the memory specified by the buffers in
+the sequence. The program shall ensure the memory remains valid until:
+
+[mdash] the last copy of the buffer sequence is destroyed, or
+
+[mdash] the completion handler for the asynchronous operation is invoked,
+
+whichever comes first.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/requirements/synchronous_socket_operations.qbk b/3rdparty/asio/src/doc/requirements/synchronous_socket_operations.qbk
new file mode 100644
index 00000000000..e6d52505c08
--- /dev/null
+++ b/3rdparty/asio/src/doc/requirements/synchronous_socket_operations.qbk
@@ -0,0 +1,37 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:synchronous_socket_operations Requirements on synchronous socket operations]
+
+In this section, ['synchronous socket operations] are those member functions
+specified as two overloads, with and without an argument of type `error_code&`:
+
+ ``[*['R f]]``(``['[*A1]]`` a1, ``['[*A2]]`` a2, ..., ``['[*AN]]`` aN);
+ ``[*['R f]]``(``['[*A1]]`` a1, ``['[*A2]]`` a2, ..., ``['[*AN]]`` aN, error_code& ec);
+
+For an object `s`, the conditions under which its synchronous socket operations
+may block the calling thread (C++Std [defns.block]) are determined as follows.
+
+If:
+
+[mdash] `s.non_blocking() == true`,
+
+[mdash] the synchronous socket operation is specified in terms of a __POSIX__
+function other than `__poll__`,
+
+[mdash] that __POSIX__ function lists `EWOULDBLOCK` or `EAGAIN`
+in its failure conditions, and
+
+[mdash] the effects of the operation cannot be established immediately
+
+then the synchronous socket operation shall not block the calling thread.
+[inline_note And the effects of the operation are not established.]
+
+Otherwise, the synchronous socket operation shall block the calling thread
+until the effects are established.
+
+[endsect]
diff --git a/3rdparty/asio/src/doc/std_exception_dox.txt b/3rdparty/asio/src/doc/std_exception_dox.txt
new file mode 100644
index 00000000000..b355e29afe8
--- /dev/null
+++ b/3rdparty/asio/src/doc/std_exception_dox.txt
@@ -0,0 +1,7 @@
+/**
+\namespace std
+*/
+
+/**
+\class std::exception
+*/
diff --git a/3rdparty/asio/src/doc/tutorial.dox b/3rdparty/asio/src/doc/tutorial.dox
new file mode 100644
index 00000000000..1dac40d2c29
--- /dev/null
+++ b/3rdparty/asio/src/doc/tutorial.dox
@@ -0,0 +1,226 @@
+# Doxyfile 1.4.5
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "Asio Tutorial"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = .
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = ./../../
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ./../examples/cpp03/tutorial/index_dox.txt \
+ ./../examples/cpp03/tutorial/timer_dox.txt \
+ ./../examples/cpp03/tutorial/daytime_dox.txt \
+ ./boost_bind_dox.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH = ./../examples
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = GENERATING_DOCUMENTATION
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES = reference.tags
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = YES
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = NO
+INCLUDED_BY_GRAPH = NO
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = NO
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = NO
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/3rdparty/asio/src/doc/tutorial.qbk b/3rdparty/asio/src/doc/tutorial.qbk
new file mode 100644
index 00000000000..e68c9362f0d
--- /dev/null
+++ b/3rdparty/asio/src/doc/tutorial.qbk
@@ -0,0 +1,2227 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:tutorial Tutorial]
+
+[heading Basic Skills]
+
+The tutorial programs in this first section introduce the fundamental concepts required to use the asio toolkit. Before plunging into the complex world of network programming, these tutorial programs illustrate the basic skills using simple asynchronous timers.
+
+* [link asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously]
+
+
+* [link asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]
+
+
+* [link asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler]
+
+
+* [link asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler]
+
+
+* [link asio.tutorial.tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs]
+
+
+
+
+[heading Introduction to Sockets]
+
+The tutorial programs in this section show how to use asio to develop simple client and server programs. These tutorial programs are based around the [@http://www.ietf.org/rfc/rfc867.txt daytime] protocol, which supports both TCP and UDP.
+
+The first three tutorial programs implement the daytime protocol using TCP.
+
+* [link asio.tutorial.tutdaytime1 Daytime.1 - A synchronous TCP daytime client]
+
+
+* [link asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]
+
+
+* [link asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]
+
+
+
+The next three tutorial programs implement the daytime protocol using UDP.
+
+* [link asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client]
+
+
+* [link asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server]
+
+
+* [link asio.tutorial.tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]
+
+
+
+The last tutorial program in this section demonstrates how asio allows the TCP and UDP servers to be easily combined into a single program.
+
+* [link asio.tutorial.tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server]
+
+
+
+
+[section:tuttimer1 Timer.1 - Using a timer synchronously]
+
+This tutorial program introduces asio by showing how to perform a blocking wait on a timer.
+
+
+
+
+
+We start by including the necessary header files.
+
+All of the asio classes can be used by simply including the `"asio.hpp"` header file.
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+
+
+
+Since this example uses timers, we need to include the appropriate Boost.Date\_Time header file for manipulating times.
+
+
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+
+All programs that use asio need to have at least one asio::io\_service object. This class provides access to I/O functionality. We declare an object of this type first thing in the main function.
+
+
+
+
+
+Next we declare an object of type asio::deadline\_timer. The core asio classes that provide I/O functionality (or as in this case timer functionality) always take a reference to an io\_service as their first constructor argument. The second argument to the constructor sets the timer to expire 5 seconds from now.
+
+
+
+
+
+In this simple example we perform a blocking wait on the timer. That is, the call to [link asio.reference.basic_deadline_timer.wait deadline_timer::wait()] will not return until the timer has expired, 5 seconds after it was created (i.e. not from when the wait starts).
+
+A deadline timer is always in one of two states: "expired" or "not expired". If the [link asio.reference.basic_deadline_timer.wait deadline_timer::wait()] function is called on an expired timer, it will return immediately.
+
+
+
+
+
+Finally we print the obligatory `"Hello, world!"` message to show when the timer has expired.
+
+
+
+
+
+See the [link asio.tutorial.tuttimer1.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Next: [link asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]
+
+
+
+[section:src Source listing for Timer.1]
+
+
+ ``''''''``//
+ ``''''''``// timer.cpp
+ ``''''''``// ~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+
+ ``''''''`` asio::deadline_timer t(io, boost::posix_time::seconds(5));
+ ``''''''`` t.wait();
+
+ ``''''''`` std::cout << "Hello, world!" << std::endl;
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously]
+
+[endsect]
+
+[endsect]
+
+[section:tuttimer2 Timer.2 - Using a timer asynchronously]
+
+This tutorial program demonstrates how to use asio's asynchronous callback functionality by modifying the program from tutorial Timer.1 to perform an asynchronous wait on the timer.
+
+
+
+
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+
+Using asio's asynchronous functionality means having a callback function that will be called when an asynchronous operation completes. In this program we define a function called `print` to be called when the asynchronous wait finishes.
+
+
+
+ ``''''''``void print(const asio::error_code& /*e*/)
+ ``''''''``{
+ ``''''''`` std::cout << "Hello, world!" << std::endl;
+ ``''''''``}
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+
+ ``''''''`` asio::deadline_timer t(io, boost::posix_time::seconds(5));
+
+
+
+Next, instead of doing a blocking wait as in tutorial Timer.1, we call the [link asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] function to perform an asynchronous wait. When calling this function we pass the `print` callback handler that was defined above.
+
+
+ ``''''''`` t.async_wait(&print);
+
+
+
+Finally, we must call the [link asio.reference.io_context.run io_service::run()] member function on the io\_service object.
+
+The asio library provides a guarantee that callback handlers will only be called from threads that are currently calling [link asio.reference.io_context.run io_service::run()]. Therefore unless the [link asio.reference.io_context.run io_service::run()] function is called the callback for the asynchronous wait completion will never be invoked.
+
+The [link asio.reference.io_context.run io_service::run()] function will also continue to run while there is still "work" to do. In this example, the work is the asynchronous wait on the timer, so the call will not return until the timer has expired and the callback has completed.
+
+It is important to remember to give the io\_service some work to do before calling [link asio.reference.io_context.run io_service::run()]. For example, if we had omitted the above call to [link asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()], the io\_service would not have had any work to do, and consequently [link asio.reference.io_context.run io_service::run()] would have returned immediately.
+
+
+ ``''''''`` io.run();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+
+
+See the [link asio.tutorial.tuttimer2.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously]
+
+Next: [link asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler]
+
+
+
+[section:src Source listing for Timer.2]
+
+
+ ``''''''``//
+ ``''''''``// timer.cpp
+ ``''''''``// ~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+ ``''''''``void print(const asio::error_code& /*e*/)
+ ``''''''``{
+ ``''''''`` std::cout << "Hello, world!" << std::endl;
+ ``''''''``}
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+
+ ``''''''`` asio::deadline_timer t(io, boost::posix_time::seconds(5));
+ ``''''''`` t.async_wait(&print);
+
+ ``''''''`` io.run();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]
+
+[endsect]
+
+[endsect]
+
+[section:tuttimer3 Timer.3 - Binding arguments to a handler]
+
+In this tutorial we will modify the program from tutorial Timer.2 so that the timer fires once a second. This will show how to pass additional parameters to your handler function.
+
+
+
+
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+
+To implement a repeating timer using asio you need to change the timer's expiry time in your callback function, and to then start a new asynchronous wait. Obviously this means that the callback function will need to be able to access the timer object. To this end we add two new parameters to the `print` function:
+
+* A pointer to a timer object.
+
+
+* A counter so that we can stop the program when the timer fires for the sixth time.
+
+
+
+
+ ``''''''``void print(const asio::error_code& /*e*/,
+ ``''''''`` asio::deadline_timer* t, int* count)
+ ``''''''``{
+
+
+
+As mentioned above, this tutorial program uses a counter to stop running when the timer fires for the sixth time. However you will observe that there is no explicit call to ask the io\_service to stop. Recall that in tutorial Timer.2 we learnt that the [link asio.reference.io_context.run io_service::run()] function completes when there is no more "work" to do. By not starting a new asynchronous wait on the timer when `count` reaches 5, the io\_service will run out of work and stop running.
+
+
+ ``''''''`` if (*count < 5)
+ ``''''''`` {
+ ``''''''`` std::cout << *count << std::endl;
+ ``''''''`` ++(*count);
+
+
+
+Next we move the expiry time for the timer along by one second from the previous expiry time. By calculating the new expiry time relative to the old, we can ensure that the timer does not drift away from the whole-second mark due to any delays in processing the handler.
+
+
+
+ ``''''''`` t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
+
+
+
+Then we start a new asynchronous wait on the timer. As you can see, the [link asio.tutorial.boost_bind boost::bind] function is used to associate the extra parameters with your callback handler. The [link asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] function expects a handler function (or function object) with the signature `void(const asio::error_code&)`. Binding the additional parameters converts your `print` function into a function object that matches the signature correctly.
+
+See the [@http://www.boost.org/libs/bind/bind.html Boost.Bind documentation] for more information on how to use [link asio.tutorial.boost_bind boost::bind] .
+
+In this example, the asio::placeholders::error argument to [link asio.tutorial.boost_bind boost::bind] is a named placeholder for the error object passed to the handler. When initiating the asynchronous operation, and if using [link asio.tutorial.boost_bind boost::bind] , you must specify only the arguments that match the handler's parameter list. In tutorial Timer.4 you will see that this placeholder may be elided if the parameter is not needed by the callback handler.
+
+
+
+
+
+A new `count` variable is added so that we can stop the program when the timer fires for the sixth time.
+
+
+
+
+
+As in Step 4, when making the call to [link asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] from `main` we bind the additional parameters needed for the `print` function.
+
+
+
+
+
+Finally, just to prove that the `count` variable was being used in the `print` handler function, we will print out its new value.
+
+
+
+
+
+See the [link asio.tutorial.tuttimer3.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]
+
+Next: [link asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler]
+
+
+
+[section:src Source listing for Timer.3]
+
+
+ ``''''''``//
+ ``''''''``// timer.cpp
+ ``''''''``// ~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+ ``''''''``void print(const asio::error_code& /*e*/,
+ ``''''''`` asio::deadline_timer* t, int* count)
+ ``''''''``{
+ ``''''''`` if (*count < 5)
+ ``''''''`` {
+ ``''''''`` std::cout << *count << std::endl;
+ ``''''''`` ++(*count);
+
+ ``''''''`` t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
+ ``''''''`` t->async_wait(boost::bind(print,
+ ``''''''`` asio::placeholders::error, t, count));
+ ``''''''`` }
+ ``''''''``}
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+
+ ``''''''`` int count = 0;
+ ``''''''`` asio::deadline_timer t(io, boost::posix_time::seconds(1));
+ ``''''''`` t.async_wait(boost::bind(print,
+ ``''''''`` asio::placeholders::error, &t, &count));
+
+ ``''''''`` io.run();
+
+ ``''''''`` std::cout << "Final count is " << count << std::endl;
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler]
+
+[endsect]
+
+[endsect]
+
+[section:tuttimer4 Timer.4 - Using a member function as a handler]
+
+In this tutorial we will see how to use a class member function as a callback handler. The program should execute identically to the tutorial program from tutorial Timer.3.
+
+
+
+
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+
+Instead of defining a free function `print` as the callback handler, as we did in the earlier tutorial programs, we now define a class called `printer`.
+
+
+
+ ``''''''``class printer
+ ``''''''``{
+ ``''''''``public:
+
+
+
+The constructor of this class will take a reference to the io\_service object and use it when initialising the `timer_` member. The counter used to shut down the program is now also a member of the class.
+
+
+ ``''''''`` printer(asio::io_context& io)
+ ``''''''`` : timer_(io, boost::posix_time::seconds(1)),
+ ``''''''`` count_(0)
+ ``''''''`` {
+
+
+
+The [link asio.tutorial.boost_bind boost::bind] function works just as well with class member functions as with free functions. Since all non-static class member functions have an implicit `this` parameter, we need to bind `this` to the function. As in tutorial Timer.3, [link asio.tutorial.boost_bind boost::bind] converts our callback handler (now a member function) into a function object that can be invoked as though it has the signature `void(const asio::error_code&)`.
+
+You will note that the asio::placeholders::error placeholder is not specified here, as the `print` member function does not accept an error object as a parameter.
+
+
+ ``''''''`` timer_.async_wait(boost::bind(&printer::print, this));
+ ``''''''`` }
+
+
+
+In the class destructor we will print out the final value of the counter.
+
+
+
+ ``''''''`` ~printer()
+ ``''''''`` {
+ ``''''''`` std::cout << "Final count is " << count_ << std::endl;
+ ``''''''`` }
+
+
+
+The `print` member function is very similar to the `print` function from tutorial Timer.3, except that it now operates on the class data members instead of having the timer and counter passed in as parameters.
+
+
+
+ ``''''''`` void print()
+ ``''''''`` {
+ ``''''''`` if (count_ < 5)
+ ``''''''`` {
+ ``''''''`` std::cout << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
+ ``''''''`` timer_.async_wait(boost::bind(&printer::print, this));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` asio::deadline_timer timer_;
+ ``''''''`` int count_;
+ ``''''''``};
+
+
+
+The `main` function is much simpler than before, as it now declares a local `printer` object before running the io\_service as normal.
+
+
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+ ``''''''`` printer p(io);
+ ``''''''`` io.run();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+
+
+See the [link asio.tutorial.tuttimer4.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler]
+
+Next: [link asio.tutorial.tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs]
+
+
+
+
+
+[section:src Source listing for Timer.4]
+
+
+ ``''''''``//
+ ``''''''``// timer.cpp
+ ``''''''``// ~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+ ``''''''``class printer
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` printer(asio::io_context& io)
+ ``''''''`` : timer_(io, boost::posix_time::seconds(1)),
+ ``''''''`` count_(0)
+ ``''''''`` {
+ ``''''''`` timer_.async_wait(boost::bind(&printer::print, this));
+ ``''''''`` }
+
+ ``''''''`` ~printer()
+ ``''''''`` {
+ ``''''''`` std::cout << "Final count is " << count_ << std::endl;
+ ``''''''`` }
+
+ ``''''''`` void print()
+ ``''''''`` {
+ ``''''''`` if (count_ < 5)
+ ``''''''`` {
+ ``''''''`` std::cout << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
+ ``''''''`` timer_.async_wait(boost::bind(&printer::print, this));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` asio::deadline_timer timer_;
+ ``''''''`` int count_;
+ ``''''''``};
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+ ``''''''`` printer p(io);
+ ``''''''`` io.run();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler]
+
+[endsect]
+
+[endsect]
+
+[section:tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs]
+
+This tutorial demonstrates the use of the asio::io\_service::strand class to synchronise callback handlers in a multithreaded program.
+
+The previous four tutorials avoided the issue of handler synchronisation by calling the [link asio.reference.io_context.run io_service::run()] function from one thread only. As you already know, the asio library provides a guarantee that callback handlers will only be called from threads that are currently calling [link asio.reference.io_context.run io_service::run()]. Consequently, calling [link asio.reference.io_context.run io_service::run()] from only one thread ensures that callback handlers cannot run concurrently.
+
+The single threaded approach is usually the best place to start when developing applications using asio. The downside is the limitations it places on programs, particularly servers, including:
+
+* Poor responsiveness when handlers can take a long time to complete.
+
+
+* An inability to scale on multiprocessor systems.
+
+
+
+
+If you find yourself running into these limitations, an alternative approach is to have a pool of threads calling [link asio.reference.io_context.run io_service::run()]. However, as this allows handlers to execute concurrently, we need a method of synchronisation when handlers might be accessing a shared, thread-unsafe resource.
+
+
+
+
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+
+We start by defining a class called `printer`, similar to the class in the previous tutorial. This class will extend the previous tutorial by running two timers in parallel.
+
+
+
+ ``''''''``class printer
+ ``''''''``{
+ ``''''''``public:
+
+
+
+In addition to initialising a pair of asio::deadline\_timer members, the constructor initialises the `strand_` member, an object of type asio::io\_service::strand.
+
+An asio::io\_service::strand is an executor that guarantees that, for those handlers that are dispatched through it, an executing handler will be allowed to complete before the next one is started. This is guaranteed irrespective of the number of threads that are calling [link asio.reference.io_context.run io_service::run()]. Of course, the handlers may still execute concurrently with other handlers that were not dispatched through an asio::io\_service::strand, or were dispatched through a different asio::io\_service::strand object.
+
+
+ ``''''''`` printer(asio::io_context& io)
+ ``''''''`` : strand_(io),
+ ``''''''`` timer1_(io, boost::posix_time::seconds(1)),
+ ``''''''`` timer2_(io, boost::posix_time::seconds(1)),
+ ``''''''`` count_(0)
+ ``''''''`` {
+
+
+
+When initiating the asynchronous operations, each callback handler is "bound" to an asio::io\_service::strand object. The asio::io\_service::strand::bind\_executor() function returns a new handler that automatically dispatches its contained handler through the asio::io\_service::strand object. By binding the handlers to the same asio::io\_service::strand, we are ensuring that they cannot execute concurrently.
+
+
+ ``''''''`` timer1_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print1, this)));
+
+ ``''''''`` timer2_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print2, this)));
+ ``''''''`` }
+
+ ``''''''`` ~printer()
+ ``''''''`` {
+ ``''''''`` std::cout << "Final count is " << count_ << std::endl;
+ ``''''''`` }
+
+
+
+In a multithreaded program, the handlers for asynchronous operations should be synchronised if they access shared resources. In this tutorial, the shared resources used by the handlers (`print1` and `print2`) are `std::cout` and the `count_` data member.
+
+
+
+ ``''''''`` void print1()
+ ``''''''`` {
+ ``''''''`` if (count_ < 10)
+ ``''''''`` {
+ ``''''''`` std::cout << "Timer 1: " << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
+
+ ``''''''`` timer1_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print1, this)));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''`` void print2()
+ ``''''''`` {
+ ``''''''`` if (count_ < 10)
+ ``''''''`` {
+ ``''''''`` std::cout << "Timer 2: " << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
+
+ ``''''''`` timer2_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print2, this)));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` asio::io_context::strand strand_;
+ ``''''''`` asio::deadline_timer timer1_;
+ ``''''''`` asio::deadline_timer timer2_;
+ ``''''''`` int count_;
+ ``''''''``};
+
+
+
+The `main` function now causes [link asio.reference.io_context.run io_service::run()] to be called from two threads: the main thread and one additional thread. This is accomplished using an
+[link asio.reference.thread thread] object.
+
+Just as it would with a call from a single thread, concurrent calls to [link asio.reference.io_context.run io_service::run()] will continue to execute while there is "work" left to do. The background thread will not exit until all asynchronous operations have completed.
+
+
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+ ``''''''`` printer p(io);
+ ``''''''`` asio::thread t(boost::bind(&asio::io_context::run, &io));
+ ``''''''`` io.run();
+ ``''''''`` t.join();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+
+
+See the [link asio.tutorial.tuttimer5.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler]
+
+
+
+
+
+[section:src Source listing for Timer.5]
+
+
+ ``''''''``//
+ ``''''''``// timer.cpp
+ ``''''''``// ~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <asio.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>
+
+ ``''''''``class printer
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` printer(asio::io_context& io)
+ ``''''''`` : strand_(io),
+ ``''''''`` timer1_(io, boost::posix_time::seconds(1)),
+ ``''''''`` timer2_(io, boost::posix_time::seconds(1)),
+ ``''''''`` count_(0)
+ ``''''''`` {
+ ``''''''`` timer1_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print1, this)));
+
+ ``''''''`` timer2_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print2, this)));
+ ``''''''`` }
+
+ ``''''''`` ~printer()
+ ``''''''`` {
+ ``''''''`` std::cout << "Final count is " << count_ << std::endl;
+ ``''''''`` }
+
+ ``''''''`` void print1()
+ ``''''''`` {
+ ``''''''`` if (count_ < 10)
+ ``''''''`` {
+ ``''''''`` std::cout << "Timer 1: " << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
+
+ ``''''''`` timer1_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print1, this)));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''`` void print2()
+ ``''''''`` {
+ ``''''''`` if (count_ < 10)
+ ``''''''`` {
+ ``''''''`` std::cout << "Timer 2: " << count_ << std::endl;
+ ``''''''`` ++count_;
+
+ ``''''''`` timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
+
+ ``''''''`` timer2_.async_wait(asio::bind_executor(strand_,
+ ``''''''`` boost::bind(&printer::print2, this)));
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` asio::io_context::strand strand_;
+ ``''''''`` asio::deadline_timer timer1_;
+ ``''''''`` asio::deadline_timer timer2_;
+ ``''''''`` int count_;
+ ``''''''``};
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` asio::io_context io;
+ ``''''''`` printer p(io);
+ ``''''''`` asio::thread t(boost::bind(&asio::io_context::run, &io));
+ ``''''''`` io.run();
+ ``''''''`` t.join();
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime1 Daytime.1 - A synchronous TCP daytime client]
+
+This tutorial program shows how to use asio to implement a client application with TCP.
+
+
+
+
+
+We start by including the necessary header files.
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <asio.hpp>
+
+
+
+The purpose of this application is to access a daytime service, so we need the user to specify the server.
+
+
+
+ ``''''''``using asio::ip::tcp;
+
+ ``''''''``int main(int argc, char* argv[])
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` if (argc != 2)
+ ``''''''`` {
+ ``''''''`` std::cerr << "Usage: client <host>" << std::endl;
+ ``''''''`` return 1;
+ ``''''''`` }
+
+
+
+All programs that use asio need to have at least one asio::io\_service object.
+
+
+
+
+
+We need to turn the server name that was specified as a parameter to the application, into a TCP endpoint. To do this we use an [link asio.reference.ip__tcp.resolver ip::tcp::resolver] object.
+
+
+
+
+
+A resolver takes a query object and turns it into a list of endpoints. We construct a query using the name of the server, specified in `argv[1]`, and the name of the service, in this case `"daytime"`.
+
+
+
+
+
+The list of endpoints is returned using an iterator of type [link asio.reference.ip__basic_resolver.iterator ip::tcp::resolver::iterator]. (Note that a default constructed [link asio.reference.ip__basic_resolver.iterator ip::tcp::resolver::iterator] object can be used as an end iterator.)
+
+
+
+
+
+Now we create and connect the socket. The list of endpoints obtained above may contain both IPv4 and IPv6 endpoints, so we need to try each of them until we find one that works. This keeps the client program independent of a specific IP version. The asio::connect() function does this for us automatically.
+
+
+
+
+
+The connection is open. All we need to do now is read the response from the daytime service.
+
+We use a `boost::array` to hold the received data. The asio::buffer() function automatically determines the size of the array to help prevent buffer overruns. Instead of a `boost::array`, we could have used a `char []` or `std::vector`.
+
+
+
+
+
+When the server closes the connection, the [link asio.reference.basic_stream_socket.read_some ip::tcp::socket::read_some()] function will exit with the asio::error::eof error, which is how we know to exit the loop.
+
+
+
+
+
+Finally, handle any exceptions that may have been thrown.
+
+
+
+
+
+See the [link asio.tutorial.tutdaytime1.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Next: [link asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]
+
+
+
+[section:src Source listing for Daytime.1]
+
+
+ ``''''''``//
+ ``''''''``// client.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::tcp;
+
+ ``''''''``int main(int argc, char* argv[])
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` if (argc != 2)
+ ``''''''`` {
+ ``''''''`` std::cerr << "Usage: client <host>" << std::endl;
+ ``''''''`` return 1;
+ ``''''''`` }
+
+ ``''''''`` asio::io_context io_context;
+
+ ``''''''`` tcp::resolver resolver(io_context);
+ ``''''''`` tcp::resolver::results_type endpoints =
+ ``''''''`` resolver.resolve(argv[1], "daytime");
+
+ ``''''''`` tcp::socket socket(io_context);
+ ``''''''`` asio::connect(socket, endpoints);
+
+ ``''''''`` for (;;)
+ ``''''''`` {
+ ``''''''`` boost::array<char, 128> buf;
+ ``''''''`` asio::error_code error;
+
+ ``''''''`` size_t len = socket.read_some(asio::buffer(buf), error);
+
+ ``''''''`` if (error == asio::error::eof)
+ ``''''''`` break; // Connection closed cleanly by peer.
+ ``''''''`` else if (error)
+ ``''''''`` throw asio::system_error(error); // Some other error.
+
+ ``''''''`` std::cout.write(buf.data(), len);
+ ``''''''`` }
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime1 Daytime.1 - A synchronous TCP daytime client]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime2 Daytime.2 - A synchronous TCP daytime server]
+
+This tutorial program shows how to use asio to implement a server application with TCP.
+
+
+
+
+
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::tcp;
+
+
+
+We define the function `make_daytime_string()` to create the string to be sent back to the client. This function will be reused in all of our daytime server applications.
+
+
+
+
+
+A [link asio.reference.ip__tcp.acceptor ip::tcp::acceptor] object needs to be created to listen for new connections. It is initialised to listen on TCP port 13, for IP version 4.
+
+
+
+
+
+This is an iterative server, which means that it will handle one connection at a time. Create a socket that will represent the connection to the client, and then wait for a connection.
+
+
+
+
+
+A client is accessing our service. Determine the current time and transfer this information to the client.
+
+
+
+
+
+Finally, handle any exceptions.
+
+
+
+
+
+See the [link asio.tutorial.tutdaytime2.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime1 Daytime.1 - A synchronous TCP daytime client]
+
+Next: [link asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]
+
+
+
+[section:src Source listing for Daytime.2]
+
+
+ ``''''''``//
+ ``''''''``// server.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::tcp;
+
+ ``''''''``std::string make_daytime_string()
+ ``''''''``{
+ ``''''''`` using namespace std; // For time_t, time and ctime;
+ ``''''''`` time_t now = time(0);
+ ``''''''`` return ctime(&now);
+ ``''''''``}
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` asio::io_context io_context;
+
+ ``''''''`` tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));
+
+ ``''''''`` for (;;)
+ ``''''''`` {
+ ``''''''`` tcp::socket socket(io_context);
+ ``''''''`` acceptor.accept(socket);
+
+ ``''''''`` std::string message = make_daytime_string();
+
+ ``''''''`` asio::error_code ignored_error;
+ ``''''''`` asio::write(socket, asio::buffer(message), ignored_error);
+ ``''''''`` }
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]
+
+[heading The main() function]
+
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+
+
+
+We need to create a server object to accept incoming client connections. The asio::io\_service object provides I/O services, such as sockets, that the server object will use.
+
+
+ ``''''''`` asio::io_context io_context;
+ ``''''''`` tcp_server server(io_context);
+
+
+
+Run the asio::io\_service object so that it will perform asynchronous operations on your behalf.
+
+
+ ``''''''`` io_context.run();
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+
+
+[heading The tcp_server class]
+
+
+ ``''''''``class tcp_server
+ ``''''''``{
+ ``''''''``public:
+
+
+
+The constructor initialises an acceptor to listen on TCP port 13.
+
+
+ ``''''''`` tcp_server(asio::io_context& io_context)
+ ``''''''`` : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''``private:
+
+
+
+The function `start_accept()` creates a socket and initiates an asynchronous accept operation to wait for a new connection.
+
+
+ ``''''''`` void start_accept()
+ ``''''''`` {
+ ``''''''`` tcp_connection::pointer new_connection =
+ ``''''''`` tcp_connection::create(acceptor_.get_executor().context());
+
+ ``''''''`` acceptor_.async_accept(new_connection->socket(),
+ ``''''''`` boost::bind(&tcp_server::handle_accept, this, new_connection,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+
+
+The function `handle_accept()` is called when the asynchronous accept operation initiated by `start_accept()` finishes. It services the client request, and then calls `start_accept()` to initiate the next accept operation.
+
+
+
+ ``''''''`` void handle_accept(tcp_connection::pointer new_connection,
+ ``''''''`` const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error)
+ ``''''''`` {
+ ``''''''`` new_connection->start();
+ ``''''''`` }
+
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+
+
+[heading The tcp_connection class]
+
+We will use `shared_ptr` and `enable_shared_from_this` because we want to keep the `tcp_connection` object alive as long as there is an operation that refers to it.
+
+
+ ``''''''``class tcp_connection
+ ``''''''`` : public boost::enable_shared_from_this<tcp_connection>
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` typedef boost::shared_ptr<tcp_connection> pointer;
+
+ ``''''''`` static pointer create(asio::io_context& io_context)
+ ``''''''`` {
+ ``''''''`` return pointer(new tcp_connection(io_context));
+ ``''''''`` }
+
+ ``''''''`` tcp::socket& socket()
+ ``''''''`` {
+ ``''''''`` return socket_;
+ ``''''''`` }
+
+
+
+In the function `start()`, we call asio::async\_write() to serve the data to the client. Note that we are using asio::async\_write(), rather than [link asio.reference.basic_stream_socket.async_write_some ip::tcp::socket::async_write_some()], to ensure that the entire block of data is sent.
+
+
+
+ ``''''''`` void start()
+ ``''''''`` {
+
+
+
+The data to be sent is stored in the class member `message_` as we need to keep the data valid until the asynchronous operation is complete.
+
+
+ ``''''''`` message_ = make_daytime_string();
+
+
+
+When initiating the asynchronous operation, and if using [link asio.tutorial.boost_bind boost::bind] , you must specify only the arguments that match the handler's parameter list. In this program, both of the argument placeholders (asio::placeholders::error and asio::placeholders::bytes\_transferred) could potentially have been removed, since they are not being used in `handle_write()`.
+
+
+
+ ``''''''`` asio::async_write(socket_, asio::buffer(message_),
+ ``''''''`` boost::bind(&tcp_connection::handle_write, shared_from_this(),
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+
+
+
+Any further actions for this client connection are now the responsibility of `handle_write()`.
+
+
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` tcp_connection(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` void handle_write(const asio::error_code& /*error*/,
+ ``''''''`` size_t /*bytes_transferred*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` tcp::socket socket_;
+ ``''''''`` std::string message_;
+ ``''''''``};
+
+
+
+[heading Removing unused handler parameters]
+
+You may have noticed that the `error`, and `bytes_transferred` parameters are not used in the body of the `handle_write()` function. If parameters are not needed, it is possible to remove them from the function so that it looks like:
+
+
+ ``''''''`` void handle_write()
+ ``''''''`` {
+ ``''''''`` }
+
+
+
+The asio::async\_write() call used to initiate the call can then be changed to just:
+
+
+ ``''''''`` asio::async_write(socket_, asio::buffer(message_),
+ ``''''''`` boost::bind(&tcp_connection::handle_write, shared_from_this()));
+
+
+
+See the [link asio.tutorial.tutdaytime3.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]
+
+Next: [link asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client]
+
+
+
+[section:src Source listing for Daytime.3]
+
+
+ ``''''''``//
+ ``''''''``// server.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/shared_ptr.hpp>
+ ``''''''``#include <boost/enable_shared_from_this.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::tcp;
+
+ ``''''''``std::string make_daytime_string()
+ ``''''''``{
+ ``''''''`` using namespace std; // For time_t, time and ctime;
+ ``''''''`` time_t now = time(0);
+ ``''''''`` return ctime(&now);
+ ``''''''``}
+
+ ``''''''``class tcp_connection
+ ``''''''`` : public boost::enable_shared_from_this<tcp_connection>
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` typedef boost::shared_ptr<tcp_connection> pointer;
+
+ ``''''''`` static pointer create(asio::io_context& io_context)
+ ``''''''`` {
+ ``''''''`` return pointer(new tcp_connection(io_context));
+ ``''''''`` }
+
+ ``''''''`` tcp::socket& socket()
+ ``''''''`` {
+ ``''''''`` return socket_;
+ ``''''''`` }
+
+ ``''''''`` void start()
+ ``''''''`` {
+ ``''''''`` message_ = make_daytime_string();
+
+ ``''''''`` asio::async_write(socket_, asio::buffer(message_),
+ ``''''''`` boost::bind(&tcp_connection::handle_write, shared_from_this(),
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` tcp_connection(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` void handle_write(const asio::error_code& /*error*/,
+ ``''''''`` size_t /*bytes_transferred*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` tcp::socket socket_;
+ ``''''''`` std::string message_;
+ ``''''''``};
+
+ ``''''''``class tcp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` tcp_server(asio::io_context& io_context)
+ ``''''''`` : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_accept()
+ ``''''''`` {
+ ``''''''`` tcp_connection::pointer new_connection =
+ ``''''''`` tcp_connection::create(acceptor_.get_executor().context());
+
+ ``''''''`` acceptor_.async_accept(new_connection->socket(),
+ ``''''''`` boost::bind(&tcp_server::handle_accept, this, new_connection,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+ ``''''''`` void handle_accept(tcp_connection::pointer new_connection,
+ ``''''''`` const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error)
+ ``''''''`` {
+ ``''''''`` new_connection->start();
+ ``''''''`` }
+
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''`` tcp::acceptor acceptor_;
+ ``''''''``};
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` asio::io_context io_context;
+ ``''''''`` tcp_server server(io_context);
+ ``''''''`` io_context.run();
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime4 Daytime.4 - A synchronous UDP daytime client]
+
+This tutorial program shows how to use asio to implement a client application with UDP.
+
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::udp;
+
+
+
+The start of the application is essentially the same as for the TCP daytime client.
+
+
+
+
+
+We use an [link asio.reference.ip__udp.resolver ip::udp::resolver] object to find the correct remote endpoint to use based on the host and service names. The query is restricted to return only IPv4 endpoints by the [link asio.reference.ip__udp.v4 ip::udp::v4()] argument.
+
+
+
+
+
+The [link asio.reference.ip__basic_resolver.resolve ip::udp::resolver::resolve()] function is guaranteed to return at least one endpoint in the list if it does not fail. This means it is safe to dereference the return value directly.
+
+
+
+
+
+Since UDP is datagram-oriented, we will not be using a stream socket. Create an [link asio.reference.ip__udp.socket ip::udp::socket] and initiate contact with the remote endpoint.
+
+
+
+
+
+Now we need to be ready to accept whatever the server sends back to us. The endpoint on our side that receives the server's response will be initialised by [link asio.reference.basic_datagram_socket.receive_from ip::udp::socket::receive_from()].
+
+
+
+
+
+Finally, handle any exceptions that may have been thrown.
+
+
+
+See the [link asio.tutorial.tutdaytime4.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]
+
+Next: [link asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server]
+
+
+
+[section:src Source listing for Daytime.4]
+
+
+ ``''''''``//
+ ``''''''``// client.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <iostream>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::udp;
+
+ ``''''''``int main(int argc, char* argv[])
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` if (argc != 2)
+ ``''''''`` {
+ ``''''''`` std::cerr << "Usage: client <host>" << std::endl;
+ ``''''''`` return 1;
+ ``''''''`` }
+
+ ``''''''`` asio::io_context io_context;
+
+ ``''''''`` udp::resolver resolver(io_context);
+ ``''''''`` udp::endpoint receiver_endpoint =
+ ``''''''`` *resolver.resolve(udp::v4(), argv[1], "daytime").begin();
+
+ ``''''''`` udp::socket socket(io_context);
+ ``''''''`` socket.open(udp::v4());
+
+ ``''''''`` boost::array<char, 1> send_buf = {{ 0 }};
+ ``''''''`` socket.send_to(asio::buffer(send_buf), receiver_endpoint);
+
+ ``''''''`` boost::array<char, 128> recv_buf;
+ ``''''''`` udp::endpoint sender_endpoint;
+ ``''''''`` size_t len = socket.receive_from(
+ ``''''''`` asio::buffer(recv_buf), sender_endpoint);
+
+ ``''''''`` std::cout.write(recv_buf.data(), len);
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime5 Daytime.5 - A synchronous UDP daytime server]
+
+This tutorial program shows how to use asio to implement a server application with UDP.
+
+
+
+
+
+Create an [link asio.reference.ip__udp.socket ip::udp::socket] object to receive requests on UDP port 13.
+
+
+
+
+
+Wait for a client to initiate contact with us. The remote\_endpoint object will be populated by [link asio.reference.basic_datagram_socket.receive_from ip::udp::socket::receive_from()].
+
+
+
+
+
+Determine what we are going to send back to the client.
+
+
+
+
+
+Send the response to the remote\_endpoint.
+
+
+
+
+
+Finally, handle any exceptions.
+
+
+
+
+
+See the [link asio.tutorial.tutdaytime5.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client]
+
+Next: [link asio.tutorial.tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]
+
+
+
+[section:src Source listing for Daytime.5]
+
+
+ ``''''''``//
+ ``''''''``// server.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::udp;
+
+ ``''''''``std::string make_daytime_string()
+ ``''''''``{
+ ``''''''`` using namespace std; // For time_t, time and ctime;
+ ``''''''`` time_t now = time(0);
+ ``''''''`` return ctime(&now);
+ ``''''''``}
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` asio::io_context io_context;
+
+ ``''''''`` udp::socket socket(io_context, udp::endpoint(udp::v4(), 13));
+
+ ``''''''`` for (;;)
+ ``''''''`` {
+ ``''''''`` boost::array<char, 1> recv_buf;
+ ``''''''`` udp::endpoint remote_endpoint;
+ ``''''''`` asio::error_code error;
+ ``''''''`` socket.receive_from(asio::buffer(recv_buf),
+ ``''''''`` remote_endpoint, 0, error);
+
+ ``''''''`` if (error && error != asio::error::message_size)
+ ``''''''`` throw asio::system_error(error);
+
+ ``''''''`` std::string message = make_daytime_string();
+
+ ``''''''`` asio::error_code ignored_error;
+ ``''''''`` socket.send_to(asio::buffer(message),
+ ``''''''`` remote_endpoint, 0, ignored_error);
+ ``''''''`` }
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]
+
+[heading The main() function]
+
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+
+
+
+Create a server object to accept incoming client requests, and run the asio::io\_service object.
+
+
+ ``''''''`` asio::io_context io_context;
+ ``''''''`` udp_server server(io_context);
+ ``''''''`` io_context.run();
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+
+
+[heading The udp_server class]
+
+
+ ``''''''``class udp_server
+ ``''''''``{
+ ``''''''``public:
+
+
+
+The constructor initialises a socket to listen on UDP port 13.
+
+
+ ``''''''`` udp_server(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_receive();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_receive()
+ ``''''''`` {
+
+
+
+The function [link asio.reference.basic_datagram_socket.async_receive_from ip::udp::socket::async_receive_from()] will cause the application to listen in the background for a new request. When such a request is received, the asio::io\_service object will invoke the `handle_receive()` function with two arguments: a value of type
+[link asio.reference.error_code error_code] indicating whether the operation succeeded or failed, and a `size_t` value `bytes_transferred` specifying the number of bytes received.
+
+
+ ``''''''`` socket_.async_receive_from(
+ ``''''''`` asio::buffer(recv_buffer_), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_receive, this,
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+ ``''''''`` }
+
+
+
+The function `handle_receive()` will service the client request.
+
+
+
+ ``''''''`` void handle_receive(const asio::error_code& error,
+ ``''''''`` std::size_t /*bytes_transferred*/)
+ ``''''''`` {
+
+
+
+The `error` parameter contains the result of the asynchronous operation. Since we only provide the 1-byte `recv_buffer_` to contain the client's request, the asio::io\_service object would return an error if the client sent anything larger. We can ignore such an error if it comes up.
+
+
+ ``''''''`` if (!error || error == asio::error::message_size)
+ ``''''''`` {
+
+
+
+Determine what we are going to send.
+
+
+ ``''''''`` boost::shared_ptr<std::string> message(
+ ``''''''`` new std::string(make_daytime_string()));
+
+
+
+We now call [link asio.reference.basic_datagram_socket.async_send_to ip::udp::socket::async_send_to()] to serve the data to the client.
+
+
+
+ ``''''''`` socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_send, this, message,
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+
+
+
+When initiating the asynchronous operation, and if using [link asio.tutorial.boost_bind boost::bind] , you must specify only the arguments that match the handler's parameter list. In this program, both of the argument placeholders (asio::placeholders::error and asio::placeholders::bytes\_transferred) could potentially have been removed.
+
+Start listening for the next client request.
+
+
+
+ ``''''''`` start_receive();
+
+
+
+Any further actions for this client request are now the responsibility of `handle_send()`.
+
+
+ ``''''''`` }
+ ``''''''`` }
+
+
+
+The function `handle_send()` is invoked after the service request has been completed.
+
+
+
+ ``''''''`` void handle_send(boost::shared_ptr<std::string> /*message*/,
+ ``''''''`` const asio::error_code& /*error*/,
+ ``''''''`` std::size_t /*bytes_transferred*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` udp::socket socket_;
+ ``''''''`` udp::endpoint remote_endpoint_;
+ ``''''''`` boost::array<char, 1> recv_buffer_;
+ ``''''''``};
+
+
+
+See the [link asio.tutorial.tutdaytime6.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server]
+
+Next: [link asio.tutorial.tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server]
+
+
+
+[section:src Source listing for Daytime.6]
+
+
+ ``''''''``//
+ ``''''''``// server.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/shared_ptr.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::udp;
+
+ ``''''''``std::string make_daytime_string()
+ ``''''''``{
+ ``''''''`` using namespace std; // For time_t, time and ctime;
+ ``''''''`` time_t now = time(0);
+ ``''''''`` return ctime(&now);
+ ``''''''``}
+
+ ``''''''``class udp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` udp_server(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_receive();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_receive()
+ ``''''''`` {
+ ``''''''`` socket_.async_receive_from(
+ ``''''''`` asio::buffer(recv_buffer_), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_receive, this,
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+ ``''''''`` }
+
+ ``''''''`` void handle_receive(const asio::error_code& error,
+ ``''''''`` std::size_t /*bytes_transferred*/)
+ ``''''''`` {
+ ``''''''`` if (!error || error == asio::error::message_size)
+ ``''''''`` {
+ ``''''''`` boost::shared_ptr<std::string> message(
+ ``''''''`` new std::string(make_daytime_string()));
+
+ ``''''''`` socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_send, this, message,
+ ``''''''`` asio::placeholders::error,
+ ``''''''`` asio::placeholders::bytes_transferred));
+
+ ``''''''`` start_receive();
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''`` void handle_send(boost::shared_ptr<std::string> /*message*/,
+ ``''''''`` const asio::error_code& /*error*/,
+ ``''''''`` std::size_t /*bytes_transferred*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` udp::socket socket_;
+ ``''''''`` udp::endpoint remote_endpoint_;
+ ``''''''`` boost::array<char, 1> recv_buffer_;
+ ``''''''``};
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` asio::io_context io_context;
+ ``''''''`` udp_server server(io_context);
+ ``''''''`` io_context.run();
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]
+
+[endsect]
+
+[endsect]
+
+[section:tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server]
+
+This tutorial program shows how to combine the two asynchronous servers that we have just written, into a single server application.
+
+[heading The main() function]
+
+
+
+
+
+We will begin by creating a server object to accept a TCP client connection.
+
+
+
+
+
+We also need a server object to accept a UDP client request.
+
+
+
+
+
+We have created two lots of work for the asio::io\_service object to do.
+
+
+
+
+
+[heading The tcp_connection and tcp_server classes]
+
+The following two classes are taken from [link asio.tutorial.tutdaytime3 Daytime.3] .
+
+
+ ``''''''``class tcp_connection
+ ``''''''`` : public boost::enable_shared_from_this<tcp_connection>
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` typedef boost::shared_ptr<tcp_connection> pointer;
+
+ ``''''''`` static pointer create(asio::io_context& io_context)
+ ``''''''`` {
+ ``''''''`` return pointer(new tcp_connection(io_context));
+ ``''''''`` }
+
+ ``''''''`` tcp::socket& socket()
+ ``''''''`` {
+ ``''''''`` return socket_;
+ ``''''''`` }
+
+ ``''''''`` void start()
+ ``''''''`` {
+ ``''''''`` message_ = make_daytime_string();
+
+ ``''''''`` asio::async_write(socket_, asio::buffer(message_),
+ ``''''''`` boost::bind(&tcp_connection::handle_write, shared_from_this()));
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` tcp_connection(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` void handle_write()
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` tcp::socket socket_;
+ ``''''''`` std::string message_;
+ ``''''''``};
+
+ ``''''''``class tcp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` tcp_server(asio::io_context& io_context)
+ ``''''''`` : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_accept()
+ ``''''''`` {
+ ``''''''`` tcp_connection::pointer new_connection =
+ ``''''''`` tcp_connection::create(acceptor_.get_executor().context());
+
+ ``''''''`` acceptor_.async_accept(new_connection->socket(),
+ ``''''''`` boost::bind(&tcp_server::handle_accept, this, new_connection,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+ ``''''''`` void handle_accept(tcp_connection::pointer new_connection,
+ ``''''''`` const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error)
+ ``''''''`` {
+ ``''''''`` new_connection->start();
+ ``''''''`` }
+
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''`` tcp::acceptor acceptor_;
+ ``''''''``};
+
+
+
+[heading The udp_server class]
+
+Similarly, this next class is taken from the [link asio.tutorial.tutdaytime6 previous tutorial step] .
+
+
+ ``''''''``class udp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` udp_server(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_receive();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_receive()
+ ``''''''`` {
+ ``''''''`` socket_.async_receive_from(
+ ``''''''`` asio::buffer(recv_buffer_), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_receive, this,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+ ``''''''`` void handle_receive(const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error || error == asio::error::message_size)
+ ``''''''`` {
+ ``''''''`` boost::shared_ptr<std::string> message(
+ ``''''''`` new std::string(make_daytime_string()));
+
+ ``''''''`` socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_send, this, message));
+
+ ``''''''`` start_receive();
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''`` void handle_send(boost::shared_ptr<std::string> /*message*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` udp::socket socket_;
+ ``''''''`` udp::endpoint remote_endpoint_;
+ ``''''''`` boost::array<char, 1> recv_buffer_;
+ ``''''''``};
+
+
+
+See the [link asio.tutorial.tutdaytime7.src full source listing]
+
+Return to the [link asio.tutorial tutorial index]
+
+Previous: [link asio.tutorial.tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]
+
+
+
+[section:src Source listing for Daytime.7]
+
+
+ ``''''''``//
+ ``''''''``// server.cpp
+ ``''''''``// ~~~~~~~~~~
+ ``''''''``//
+ ``''''''``// Copyright (c) 2003-2016 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)
+ ``''''''``//
+
+ ``''''''``#include <ctime>
+ ``''''''``#include <iostream>
+ ``''''''``#include <string>
+ ``''''''``#include <boost/array.hpp>
+ ``''''''``#include <boost/bind.hpp>
+ ``''''''``#include <boost/shared_ptr.hpp>
+ ``''''''``#include <boost/enable_shared_from_this.hpp>
+ ``''''''``#include <asio.hpp>
+
+ ``''''''``using asio::ip::tcp;
+ ``''''''``using asio::ip::udp;
+
+ ``''''''``std::string make_daytime_string()
+ ``''''''``{
+ ``''''''`` using namespace std; // For time_t, time and ctime;
+ ``''''''`` time_t now = time(0);
+ ``''''''`` return ctime(&now);
+ ``''''''``}
+
+ ``''''''``class tcp_connection
+ ``''''''`` : public boost::enable_shared_from_this<tcp_connection>
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` typedef boost::shared_ptr<tcp_connection> pointer;
+
+ ``''''''`` static pointer create(asio::io_context& io_context)
+ ``''''''`` {
+ ``''''''`` return pointer(new tcp_connection(io_context));
+ ``''''''`` }
+
+ ``''''''`` tcp::socket& socket()
+ ``''''''`` {
+ ``''''''`` return socket_;
+ ``''''''`` }
+
+ ``''''''`` void start()
+ ``''''''`` {
+ ``''''''`` message_ = make_daytime_string();
+
+ ``''''''`` asio::async_write(socket_, asio::buffer(message_),
+ ``''''''`` boost::bind(&tcp_connection::handle_write, shared_from_this()));
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` tcp_connection(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` void handle_write()
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` tcp::socket socket_;
+ ``''''''`` std::string message_;
+ ``''''''``};
+
+ ``''''''``class tcp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` tcp_server(asio::io_context& io_context)
+ ``''''''`` : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_accept()
+ ``''''''`` {
+ ``''''''`` tcp_connection::pointer new_connection =
+ ``''''''`` tcp_connection::create(acceptor_.get_executor().context());
+
+ ``''''''`` acceptor_.async_accept(new_connection->socket(),
+ ``''''''`` boost::bind(&tcp_server::handle_accept, this, new_connection,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+ ``''''''`` void handle_accept(tcp_connection::pointer new_connection,
+ ``''''''`` const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error)
+ ``''''''`` {
+ ``''''''`` new_connection->start();
+ ``''''''`` }
+
+ ``''''''`` start_accept();
+ ``''''''`` }
+
+ ``''''''`` tcp::acceptor acceptor_;
+ ``''''''``};
+
+ ``''''''``class udp_server
+ ``''''''``{
+ ``''''''``public:
+ ``''''''`` udp_server(asio::io_context& io_context)
+ ``''''''`` : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ ``''''''`` {
+ ``''''''`` start_receive();
+ ``''''''`` }
+
+ ``''''''``private:
+ ``''''''`` void start_receive()
+ ``''''''`` {
+ ``''''''`` socket_.async_receive_from(
+ ``''''''`` asio::buffer(recv_buffer_), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_receive, this,
+ ``''''''`` asio::placeholders::error));
+ ``''''''`` }
+
+ ``''''''`` void handle_receive(const asio::error_code& error)
+ ``''''''`` {
+ ``''''''`` if (!error || error == asio::error::message_size)
+ ``''''''`` {
+ ``''''''`` boost::shared_ptr<std::string> message(
+ ``''''''`` new std::string(make_daytime_string()));
+
+ ``''''''`` socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ ``''''''`` boost::bind(&udp_server::handle_send, this, message));
+
+ ``''''''`` start_receive();
+ ``''''''`` }
+ ``''''''`` }
+
+ ``''''''`` void handle_send(boost::shared_ptr<std::string> /*message*/)
+ ``''''''`` {
+ ``''''''`` }
+
+ ``''''''`` udp::socket socket_;
+ ``''''''`` udp::endpoint remote_endpoint_;
+ ``''''''`` boost::array<char, 1> recv_buffer_;
+ ``''''''``};
+
+ ``''''''``int main()
+ ``''''''``{
+ ``''''''`` try
+ ``''''''`` {
+ ``''''''`` asio::io_context io_context;
+ ``''''''`` tcp_server server1(io_context);
+ ``''''''`` udp_server server2(io_context);
+ ``''''''`` io_context.run();
+ ``''''''`` }
+ ``''''''`` catch (std::exception& e)
+ ``''''''`` {
+ ``''''''`` std::cerr << e.what() << std::endl;
+ ``''''''`` }
+
+ ``''''''`` return 0;
+ ``''''''``}
+
+Return to [link asio.tutorial.tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server]
+
+[endsect]
+
+[endsect]
+
+[section:boost_bind boost::bind]
+
+See the [@http://www.boost.org/libs/bind/bind.html Boost: bind.hpp documentation] for more information on how to use `boost::bind`.
+
+[endsect]
+
+
+[endsect] \ No newline at end of file
diff --git a/3rdparty/asio/src/doc/tutorial.xsl b/3rdparty/asio/src/doc/tutorial.xsl
new file mode 100644
index 00000000000..da9be491d53
--- /dev/null
+++ b/3rdparty/asio/src/doc/tutorial.xsl
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ Copyright (c) 2003-2016 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)
+-->
+
+<xsl:output method="text"/>
+<xsl:strip-space elements="*"/>
+
+
+<xsl:variable name="newline">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+
+<xsl:template match="/doxygen">
+<xsl:text>[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:tutorial Tutorial]
+
+</xsl:text>
+
+ <xsl:for-each select="compounddef[@kind = 'page' and @id = 'indexpage']">
+ <xsl:apply-templates select="detaileddescription"/>
+ </xsl:for-each>
+
+ <xsl:for-each select="
+ compounddef[
+ @kind = 'page' and
+ @id != 'indexpage' and
+ not(contains(@id, 'src'))]">
+ <xsl:text>[section:</xsl:text>
+ <xsl:value-of select="concat(@id, ' ', title)"/>
+ <xsl:text>]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates select="detaileddescription"/>
+ <xsl:variable name="srcid" select="concat(@id, 'src')"/>
+ <xsl:if test="count(/doxygen/compounddef[@id = $srcid]) &gt; 0">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:text>[section:src </xsl:text>
+ <xsl:value-of select="/doxygen/compounddef[@id = $srcid]/title"/>
+ <xsl:text>]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates select="/doxygen/compounddef[@id = $srcid]/detaileddescription"/>
+ <xsl:text>[endsect]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ </xsl:if>
+ <xsl:text>[endsect]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ </xsl:for-each>
+
+ <xsl:value-of select="$newline"/>
+ <xsl:text>[endsect]</xsl:text>
+
+</xsl:template>
+
+
+<!--========== Utilities ==========-->
+
+<xsl:template name="strip-asio-ns">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, 'boost::system::is_error_code_enum')">
+ <xsl:value-of select="$name"/>
+ </xsl:when>
+ <xsl:when test="contains($name, 'asio::')">
+ <xsl:value-of select="substring-after($name, 'asio::')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="make-id">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, '::')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '::'), '__', substring-after($name, '::'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '=')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '='), '_eq_', substring-after($name, '='))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '!')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '!'), '_not_', substring-after($name, '!'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '&lt;')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '&lt;'), '_lt_', substring-after($name, '&lt;'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '&gt;')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '&gt;'), '_gt_', substring-after($name, '&gt;'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '+')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '+'), '_plus_', substring-after($name, '+'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, '~')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, '~'), '_', substring-after($name, '~'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, ' ')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, ' '), '_', substring-after($name, ' '))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($name, 'boost__posix_time__ptime')">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name"
+ select="concat(substring-before($name, 'boost__posix_time__ptime'), 'ptime', substring-after($name, 'boost__posix_time__ptime'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="replace-scope-marker">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="contains($text, '_1_1')">
+ <xsl:call-template name="replace-scope-marker">
+ <xsl:with-param name="text"
+ select="concat(substring-before($text, '_1_1'), '::', substring-after($text, '_1_1'))"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="refid-to-anchor">
+ <xsl:param name="text"/>
+ <xsl:variable name="scoped-text">
+ <xsl:call-template name="replace-scope-marker">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="substring-after($scoped-text, '_1')"/>
+</xsl:template>
+
+
+<!--========== Markup ==========-->
+
+<xsl:template match="para">
+ <xsl:apply-templates/>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="title">
+ <xsl:variable name="title">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:if test="string-length($title) > 0">
+ <xsl:text>[heading </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>]</xsl:text>
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+ </xsl:if>
+</xsl:template>
+
+
+<xsl:template match="programlisting">
+ <xsl:value-of select="$newline"/>
+ <xsl:apply-templates/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="codeline">
+ <xsl:if test="string-length(.) &gt; 0">
+ <xsl:text> ``''''''``</xsl:text>
+ </xsl:if>
+ <xsl:apply-templates mode="codeline"/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="sp">
+ <xsl:text> </xsl:text>
+</xsl:template>
+
+
+<xsl:template match="sp" mode="codeline">
+ <xsl:text> </xsl:text>
+</xsl:template>
+
+
+<xsl:template match="linebreak">
+ <xsl:value-of select="$newline"/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="listitem">
+ <xsl:text>* </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:value-of select="$newline"/>
+</xsl:template>
+
+
+<xsl:template match="emphasis">
+ <xsl:text>[*</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>]</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="computeroutput">
+ <xsl:text>`</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>`</xsl:text>
+</xsl:template>
+
+
+<xsl:template match="text()">
+ <xsl:variable name="text" select="."/>
+ <xsl:variable name="starts-with-whitespace" select="
+ starts-with($text, ' ') or starts-with($text, $newline)"/>
+ <xsl:variable name="preceding-node-name">
+ <xsl:for-each select="preceding-sibling::*">
+ <xsl:if test="position() = last()">
+ <xsl:value-of select="local-name()"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="after-newline" select="
+ $preceding-node-name = 'programlisting' or
+ $preceding-node-name = 'linebreak'"/>
+ <xsl:choose>
+ <xsl:when test="$starts-with-whitespace and $after-newline">
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text" select="$text"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="strip-leading-whitespace">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($text, ' ')">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="substring($text, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="starts-with($text, $newline)">
+ <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text" select="substring($text, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="escape-text">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="contains($text, '_')">
+ <xsl:value-of select="substring-before($text, '_')"/>
+ <xsl:text>\_</xsl:text>
+ <xsl:call-template name="escape-text">
+ <xsl:with-param name="text" select="substring-after($text, '_')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='compound']">
+ <xsl:variable name="name">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:variable name="refid">
+ <xsl:value-of select="@refid"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="count(/doxygen/compounddef[@id=$refid]) &gt; 0">
+ <xsl:text>[link asio.tutorial.</xsl:text>
+ <xsl:choose>
+ <xsl:when test="contains($refid, 'src')">
+ <xsl:value-of select="substring-before($refid, 'src')"/>
+ <xsl:text>.src</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$refid"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="concat(' ', .)"/>
+ <xsl:text>]</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($name, 'asio::')">
+ <xsl:variable name="ref-name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ref-id">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="$ref-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+[link asio.reference.<xsl:value-of select="$ref-id"/><xsl:text> </xsl:text><xsl:value-of
+ select="$ref-name"/>]</xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ref[@kindref='member']">
+ <xsl:variable name="refid">
+ <xsl:value-of select="@refid"/>
+ </xsl:variable>
+ <xsl:variable name="text">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="."/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$refid='index_1index'">
+ <xsl:text>[link asio.tutorial </xsl:text>
+ <xsl:value-of select="$text"/>
+ <xsl:text>]</xsl:text>
+ </xsl:when>
+ <xsl:when test="@external='reference.tags'">
+ <xsl:variable name="anchor">
+ <xsl:call-template name="refid-to-anchor">
+ <xsl:with-param name="text" select="$refid"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="count(document('reference.tags')/tagfile/compound[@kind='class']/member[anchor=$anchor]) &gt; 0">
+ <xsl:for-each select="document('reference.tags')/tagfile/compound[@kind='class']/member[anchor=$anchor]">
+ <xsl:variable name="scope">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name">
+ <xsl:call-template name="strip-asio-ns">
+ <xsl:with-param name="name" select="../name"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="name">
+ <xsl:call-template name="make-id">
+ <xsl:with-param name="name" select="name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>[link asio.reference.</xsl:text>
+ <xsl:if test="string-length($scope) &gt; 0">
+ <xsl:value-of select="$scope"/><xsl:text>.</xsl:text>
+ </xsl:if>
+ <xsl:value-of select="$name"/>
+ <xsl:text> </xsl:text><xsl:value-of select="$text"/><xsl:text>]</xsl:text>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="ulink">
+ <xsl:text>[@</xsl:text>
+ <xsl:value-of select="@url"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>]</xsl:text>
+</xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/3rdparty/asio/src/doc/using.qbk b/3rdparty/asio/src/doc/using.qbk
new file mode 100644
index 00000000000..b4bcb01c831
--- /dev/null
+++ b/3rdparty/asio/src/doc/using.qbk
@@ -0,0 +1,316 @@
+[/
+ / Copyright (c) 2003-2016 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)
+ /]
+
+[section:using Using Asio]
+
+[heading Supported Platforms]
+
+The following platforms and compilers have been tested:
+
+* Win32 and Win64 using Visual C++ 7.1 and Visual C++ 8.0.
+* Win32 using MinGW.
+* Win32 using Cygwin. (`__USE_W32_SOCKETS` must be defined.)
+* Linux (2.4 or 2.6 kernels) using g++ 3.3 or later.
+* Solaris using g++ 3.3 or later.
+* Mac OS X 10.4 using g++ 3.3 or later.
+
+The following platforms may also work:
+
+* AIX 5.3 using XL C/C++ v9.
+* HP-UX 11i v3 using patched aC++ A.06.14.
+* QNX Neutrino 6.3 using g++ 3.3 or later.
+* Solaris using Sun Studio 11 or later.
+* Tru64 v5.1 using Compaq C++ v7.1.
+
+[heading Dependencies]
+
+The following libraries must be available in order to link programs that use
+Asio:
+
+* Boost.Regex (optional) if you use any of the [link
+asio.reference.read_until `read_until()`] or [link
+asio.reference.async_read_until `async_read_until()`] overloads that take
+a `boost::regex` parameter.
+
+* [@http://www.openssl.org OpenSSL] (optional) if you use Asio's SSL
+support.
+
+Furthermore, some of the examples also require Boost.Date_Time or
+Boost.Serialization libraries.
+
+[note With MSVC or Borland C++ you may want to add `-DBOOST_DATE_TIME_NO_LIB`
+and `-DBOOST_REGEX_NO_LIB` to your project settings to disable autolinking of
+the Boost.Date_Time and Boost.Regex libraries respectively. Alternatively, you
+may choose to build these libraries and link to them.]
+
+[heading Optional separate compilation]
+
+By default, Asio is a header-only library. However, some developers may prefer
+to build Asio using separately compiled source code. To do this, add `#include
+<asio/impl/src.hpp>` to one (and only one) source file in a program, then build
+the program with `ASIO_SEPARATE_COMPILATION` defined in the project\/compiler
+settings. Alternatively, `ASIO_DYN_LINK` may be defined to build a
+separately-compiled Asio as part of a shared library.
+
+If using Asio's SSL support, you will also need to add `#include
+<asio/ssl/impl/src.hpp>`.
+
+[heading Building the tests and examples on Linux or UNIX]
+
+If the boost directory (e.g. the directory called `boost_1_34_1`) is in the
+same directory as the asio source kit, then you may configure asio by simply
+going:
+
+ ./configure
+
+in the root directory of the asio source kit. Note that configure will always
+use the most recent boost version it knows about (i.e. 1.34.1) in preference to
+earlier versions, if there is more than one version present.
+
+If the boost directory is in some other location, then you need to
+specify this directory when running configure:
+
+ ./configure --with-boost=``['path_to_boost]``
+
+When specifying the boost directory in this way you should ensure that you use
+an absolute path.
+
+To build the examples, simply run `make` in the root directory of the asio
+source kit. To also build and run the unit tests, to confirm that asio is
+working correctly, run `make check`.
+
+[heading Building the tests and examples with MSVC]
+
+To build using the MSVC 7.1 or MSVC 8.0 command line compiler, perform the
+following steps in a Command Prompt window:
+
+* If you are using a version of boost other than 1.34.1, or if the boost
+ directory (i.e. the directory called `boost_1_34_1`) is not in the same
+ directory as the asio source kit, then specify the location of boost by
+ running a command similar to [^set BOOSTDIR=['path_to_boost]]. Ensure that
+ you specify an absolute path.
+
+* Change to the asio `src` directory.
+
+* Execute the command `nmake -f Makefile.msc`.
+
+* Execute the command `nmake -f Makefile.msc check` to run a suite of tests to
+ confirm that asio is working correctly.
+
+[heading Building the tests and examples with MinGW]
+
+To build using the MinGW g++ compiler from the command line, perform the
+following steps in a Command Prompt window:
+
+* If you are using a version of boost other than 1.34.1, or if the boost
+ directory (i.e. the directory called `boost_1_34_1`) is not in the same
+ directory as the asio source kit, then specify the location of boost by
+ running a command similar to [^set BOOSTDIR=['path_to_boost]]. Ensure that
+ you specify an absolute path using ['forward slashes] (i.e.
+ `c:/projects/boost_1_34_1` rather than `c:\projects\boost_1_34_1`).
+
+* Change to the asio `src` directory.
+
+* Execute the command `make -f Makefile.mgw`.
+
+* Execute the command `make -f Makefile.mgw check` to run a suite of tests to
+ confirm that asio is working correctly.
+
+[note The above instructions do not work when building inside MSYS. If you want
+to build using MSYS, you should use [^export] rather than [^set] to specify the
+location of boost.]
+
+[heading Macros]
+
+The macros listed in the table below may be used to control the behaviour of
+Asio.
+
+[table
+ [[Macro][Description]]
+ [
+ [`ASIO_ENABLE_BUFFER_DEBUGGING`]
+ [
+ Enables Asio's buffer debugging support, which can help identify when
+ invalid buffers are used in read or write operations (e.g. if a
+ std::string object being written is destroyed before the write operation
+ completes).
+
+ When using Microsoft Visual C++, this macro is defined automatically if
+ the compiler's iterator debugging support is enabled, unless
+ `ASIO_DISABLE_BUFFER_DEBUGGING` has been defined.
+
+ When using g++, this macro is defined automatically if standard library
+ debugging is enabled (`_GLIBCXX_DEBUG` is defined), unless
+ `ASIO_DISABLE_BUFFER_DEBUGGING` has been defined.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_BUFFER_DEBUGGING`]
+ [
+ Explictly disables Asio's buffer debugging support.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_DEV_POLL`]
+ [
+ Explicitly disables [^/dev/poll] support on Solaris, forcing the use of
+ a `select`-based implementation.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_EPOLL`]
+ [
+ Explicitly disables `epoll` support on Linux, forcing the use of a
+ `select`-based implementation.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_EVENTFD`]
+ [
+ Explicitly disables `eventfd` support on Linux, forcing the use of a
+ pipe to interrupt blocked epoll/select system calls.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_KQUEUE`]
+ [
+ Explicitly disables `kqueue` support on Mac OS X and BSD variants,
+ forcing the use of a `select`-based implementation.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_IOCP`]
+ [
+ Explicitly disables I/O completion ports support on Windows, forcing the
+ use of a `select`-based implementation.
+ ]
+ ]
+ [
+ [`ASIO_DISABLE_THREADS`]
+ [
+ Explicitly disables Asio's threading support, independent of whether or
+ not Boost supports threads.
+ ]
+ ]
+ [
+ [`ASIO_NO_WIN32_LEAN_AND_MEAN`]
+ [
+ By default, Asio will automatically define `WIN32_LEAN_AND_MEAN` when
+ compiling for Windows, to minimise the number of Windows SDK header files
+ and features that are included. The presence of
+ `ASIO_NO_WIN32_LEAN_AND_MEAN` prevents `WIN32_LEAN_AND_MEAN` from
+ being defined.
+ ]
+ ]
+ [
+ [`ASIO_NO_NOMINMAX`]
+ [
+ By default, Asio will automatically define `NOMINMAX` when compiling for
+ Windows, to suppress the definition of the `min()` and `max()` macros.
+ The presence of `ASIO_NO_NOMINMAX` prevents `NOMINMAX` from being
+ defined.
+ ]
+ ]
+ [
+ [`ASIO_NO_DEFAULT_LINKED_LIBS`]
+ [
+ When compiling for Windows using Microsoft Visual C++ or Borland C++, Asio
+ will automatically link in the necessary Windows SDK libraries for sockets
+ support (i.e. [^ws2_32.lib] and [^mswsock.lib], or [^ws2.lib] when
+ building for Windows CE). The `ASIO_NO_DEFAULT_LINKED_LIBS` macro
+ prevents these libraries from being linked.
+ ]
+ ]
+ [
+ [`ASIO_SOCKET_STREAMBUF_MAX_ARITY`]
+ [
+ Determines the maximum number of arguments that may be passed to the
+ `basic_socket_streambuf` class template's `connect` member function.
+ Defaults to 5.
+ ]
+ ]
+ [
+ [`ASIO_SOCKET_IOSTREAM_MAX_ARITY`]
+ [
+ Determines the maximum number of arguments that may be passed to the
+ `basic_socket_iostream` class template's constructor and `connect` member
+ function. Defaults to 5.
+ ]
+ ]
+ [
+ [`ASIO_ENABLE_CANCELIO`]
+ [
+ Enables use of the `CancelIo` function on older versions of Windows. If
+ not enabled, calls to `cancel()` on a socket object will always fail with
+ `asio::error::operation_not_supported` when run on Windows XP, Windows
+ Server 2003, and earlier versions of Windows. When running on Windows
+ Vista, Windows Server 2008, and later, the `CancelIoEx` function is
+ always used.
+
+ The `CancelIo` function has two issues that should be considered before
+ enabling its use:
+
+ * It will only cancel asynchronous operations that were initiated in the
+ current thread.
+
+ * It can appear to complete without error, but the request
+ to cancel the unfinished operations may be silently ignored by the
+ operating system. Whether it works or not seems to depend on the
+ drivers that are installed.
+
+ For portable cancellation, consider using one of the following
+ alternatives:
+
+ * Disable asio's I/O completion port backend by defining
+ ASIO_DISABLE_IOCP.
+
+ * Use the socket object's close() function to simultaneously
+ cancel the outstanding operations and close the socket.
+ ]
+ ]
+ [
+ [`ASIO_NO_TYPEID`]
+ [
+ Disables uses of the `typeid` operator in asio. Defined automatically if
+ `BOOST_NO_TYPEID` is defined.
+ ]
+ ]
+ [
+ [`ASIO_HASH_MAP_BUCKETS`]
+ [
+ Determines the number of buckets in asio's internal `hash_map` objects.
+ The value should be a comma separated list of prime numbers, in ascending
+ order. The `hash_map` implementation will automatically increase the
+ number of buckets as the number of elements in the map increases.
+
+ Some examples:
+
+ * Defining `ASIO_HASH_MAP_BUCKETS` to `1021` means that the `hash_map`
+ objects will always contain 1021 buckets, irrespective of the number of
+ elements in the map.
+
+ * Defining `ASIO_HASH_MAP_BUCKETS` to `53,389,1543` means that the
+ `hash_map` objects will initially contain 53 buckets. The number of
+ buckets will be increased to 389 and then 1543 as elements are added to
+ the map.
+ ]
+ ]
+]
+
+[heading Mailing List]
+
+A mailing list specifically for Asio may be found on
+[@http://sourceforge.net/mail/?group_id=122478 SourceForge.net]. Newsgroup
+access is provided via [@http://dir.gmane.org/gmane.comp.lib.boost.asio.user
+Gmane].
+
+[heading Wiki]
+
+Users are encouraged to share examples, tips and FAQs on the Asio wiki,
+which is located at [@http://think-async.com/Asio/].
+
+[endsect]
diff --git a/3rdparty/asio/src/examples/cpp03/Makefile.am b/3rdparty/asio/src/examples/cpp03/Makefile.am
new file mode 100644
index 00000000000..adacab88ef6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/Makefile.am
@@ -0,0 +1,250 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+if SEPARATE_COMPILATION
+noinst_LIBRARIES = libasio.a
+libasio_a_SOURCES = ../../asio.cpp
+if HAVE_OPENSSL
+libasio_a_SOURCES += ../../asio_ssl.cpp
+endif
+LDADD = libasio.a
+endif
+
+noinst_PROGRAMS = \
+ allocation/server \
+ buffers/reference_counted \
+ chat/chat_client \
+ chat/chat_server \
+ echo/async_tcp_echo_server \
+ echo/async_udp_echo_server \
+ echo/blocking_tcp_echo_client \
+ echo/blocking_tcp_echo_server \
+ echo/blocking_udp_echo_client \
+ echo/blocking_udp_echo_server \
+ http/client/async_client \
+ http/client/sync_client \
+ http/server/http_server \
+ http/server2/http_server \
+ http/server3/http_server \
+ http/server4/http_server \
+ icmp/ping \
+ invocation/prioritised_handlers \
+ iostreams/daytime_client \
+ iostreams/daytime_server \
+ iostreams/http_client \
+ multicast/receiver \
+ multicast/sender \
+ nonblocking/third_party_lib \
+ porthopper/client \
+ porthopper/server \
+ services/daytime_client \
+ socks4/sync_client \
+ timeouts/async_tcp_client \
+ timeouts/blocking_tcp_client \
+ timeouts/blocking_udp_client \
+ timeouts/server \
+ timers/time_t_timer \
+ tutorial/timer1/timer \
+ tutorial/timer2/timer \
+ tutorial/timer3/timer \
+ tutorial/timer4/timer \
+ tutorial/timer5/timer \
+ tutorial/daytime1/client \
+ tutorial/daytime2/server \
+ tutorial/daytime3/server \
+ tutorial/daytime4/client \
+ tutorial/daytime5/server \
+ tutorial/daytime6/server \
+ tutorial/daytime7/server
+
+if !WINDOWS_TARGET
+noinst_PROGRAMS += \
+ chat/posix_chat_client \
+ fork/daemon \
+ fork/process_per_connection \
+ local/connect_pair \
+ local/iostream_client \
+ local/stream_server \
+ local/stream_client
+endif
+
+if WINDOWS_TARGET
+noinst_PROGRAMS += \
+ windows/transmit_file
+endif
+
+if HAVE_OPENSSL
+noinst_PROGRAMS += \
+ ssl/client \
+ ssl/server
+endif
+
+if HAVE_BOOST_COROUTINE
+noinst_PROGRAMS += \
+ spawn/echo_server \
+ spawn/parallel_grep
+endif
+
+noinst_HEADERS = \
+ chat/chat_message.hpp \
+ services/basic_logger.hpp \
+ services/logger.hpp \
+ services/logger_service.hpp
+
+AM_CXXFLAGS = -I$(srcdir)/../../../include
+
+allocation_server_SOURCES = allocation/server.cpp
+buffers_reference_counted_SOURCES = buffers/reference_counted.cpp
+chat_chat_client_SOURCES = chat/chat_client.cpp
+chat_chat_server_SOURCES = chat/chat_server.cpp
+echo_async_tcp_echo_server_SOURCES = echo/async_tcp_echo_server.cpp
+echo_async_udp_echo_server_SOURCES = echo/async_udp_echo_server.cpp
+echo_blocking_tcp_echo_client_SOURCES = echo/blocking_tcp_echo_client.cpp
+echo_blocking_tcp_echo_server_SOURCES = echo/blocking_tcp_echo_server.cpp
+echo_blocking_udp_echo_client_SOURCES = echo/blocking_udp_echo_client.cpp
+echo_blocking_udp_echo_server_SOURCES = echo/blocking_udp_echo_server.cpp
+http_client_async_client_SOURCES = http/client/async_client.cpp
+http_client_sync_client_SOURCES = http/client/sync_client.cpp
+http_server_http_server_SOURCES = \
+ http/server/connection.cpp \
+ http/server/connection_manager.cpp \
+ http/server/main.cpp \
+ http/server/mime_types.cpp \
+ http/server/reply.cpp \
+ http/server/request_handler.cpp \
+ http/server/request_parser.cpp \
+ http/server/server.cpp
+http_server2_http_server_SOURCES = \
+ http/server2/connection.cpp \
+ http/server2/io_context_pool.cpp \
+ http/server2/main.cpp \
+ http/server2/mime_types.cpp \
+ http/server2/reply.cpp \
+ http/server2/request_handler.cpp \
+ http/server2/request_parser.cpp \
+ http/server2/server.cpp
+http_server3_http_server_SOURCES = \
+ http/server3/connection.cpp \
+ http/server3/main.cpp \
+ http/server3/mime_types.cpp \
+ http/server3/reply.cpp \
+ http/server3/request_handler.cpp \
+ http/server3/request_parser.cpp \
+ http/server3/server.cpp
+http_server4_http_server_SOURCES = \
+ http/server4/file_handler.cpp \
+ http/server4/main.cpp \
+ http/server4/mime_types.cpp \
+ http/server4/reply.cpp \
+ http/server4/request_parser.cpp \
+ http/server4/server.cpp
+icmp_ping_SOURCES = icmp/ping.cpp
+invocation_prioritised_handlers_SOURCES = invocation/prioritised_handlers.cpp
+iostreams_daytime_client_SOURCES = iostreams/daytime_client.cpp
+iostreams_daytime_server_SOURCES = iostreams/daytime_server.cpp
+iostreams_http_client_SOURCES = iostreams/http_client.cpp
+multicast_receiver_SOURCES = multicast/receiver.cpp
+multicast_sender_SOURCES = multicast/sender.cpp
+nonblocking_third_party_lib_SOURCES = nonblocking/third_party_lib.cpp
+porthopper_client_SOURCES = porthopper/client.cpp
+porthopper_server_SOURCES = porthopper/server.cpp
+services_daytime_client_SOURCES = \
+ services/daytime_client.cpp \
+ services/logger_service.cpp
+socks4_sync_client_SOURCES = socks4/sync_client.cpp
+timeouts_async_tcp_client_SOURCES = timeouts/async_tcp_client.cpp
+timeouts_blocking_tcp_client_SOURCES = timeouts/blocking_tcp_client.cpp
+timeouts_blocking_udp_client_SOURCES = timeouts/blocking_udp_client.cpp
+timeouts_server_SOURCES = timeouts/server.cpp
+timers_time_t_timer_SOURCES = timers/time_t_timer.cpp
+tutorial_timer1_timer_SOURCES = tutorial/timer1/timer.cpp
+tutorial_timer2_timer_SOURCES = tutorial/timer2/timer.cpp
+tutorial_timer3_timer_SOURCES = tutorial/timer3/timer.cpp
+tutorial_timer4_timer_SOURCES = tutorial/timer4/timer.cpp
+tutorial_timer5_timer_SOURCES = tutorial/timer5/timer.cpp
+tutorial_daytime1_client_SOURCES = tutorial/daytime1/client.cpp
+tutorial_daytime2_server_SOURCES = tutorial/daytime2/server.cpp
+tutorial_daytime3_server_SOURCES = tutorial/daytime3/server.cpp
+tutorial_daytime4_client_SOURCES = tutorial/daytime4/client.cpp
+tutorial_daytime5_server_SOURCES = tutorial/daytime5/server.cpp
+tutorial_daytime6_server_SOURCES = tutorial/daytime6/server.cpp
+tutorial_daytime7_server_SOURCES = tutorial/daytime7/server.cpp
+
+if !WINDOWS_TARGET
+chat_posix_chat_client_SOURCES = chat/posix_chat_client.cpp
+fork_daemon_SOURCES = fork/daemon.cpp
+fork_process_per_connection_SOURCES = fork/process_per_connection.cpp
+local_connect_pair_SOURCES = local/connect_pair.cpp
+local_iostream_client_SOURCES = local/iostream_client.cpp
+local_stream_server_SOURCES = local/stream_server.cpp
+local_stream_client_SOURCES = local/stream_client.cpp
+endif
+
+if WINDOWS_TARGET
+windows_transmit_file_SOURCES = windows/transmit_file.cpp
+endif
+
+if HAVE_OPENSSL
+ssl_client_SOURCES = ssl/client.cpp
+ssl_server_SOURCES = ssl/server.cpp
+endif
+
+if HAVE_BOOST_COROUTINE
+spawn_echo_server_SOURCES = spawn/echo_server.cpp
+spawn_echo_server_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system
+spawn_parallel_grep_SOURCES = spawn/parallel_grep.cpp
+spawn_parallel_grep_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system
+endif
+
+EXTRA_DIST = \
+ http/server/connection.hpp \
+ http/server/connection_manager.hpp \
+ http/server/header.hpp \
+ http/server/mime_types.hpp \
+ http/server/reply.hpp \
+ http/server/request.hpp \
+ http/server/request_handler.hpp \
+ http/server/request_parser.hpp \
+ http/server/server.hpp \
+ http/server2/connection.hpp \
+ http/server2/io_context_pool.hpp \
+ http/server2/header.hpp \
+ http/server2/mime_types.hpp \
+ http/server2/reply.hpp \
+ http/server2/request.hpp \
+ http/server2/request_handler.hpp \
+ http/server2/request_parser.hpp \
+ http/server2/server.hpp \
+ http/server3/connection.hpp \
+ http/server3/header.hpp \
+ http/server3/mime_types.hpp \
+ http/server3/reply.hpp \
+ http/server3/request.hpp \
+ http/server3/request_handler.hpp \
+ http/server3/request_parser.hpp \
+ http/server3/server.hpp \
+ http/server4/file_handler.hpp \
+ http/server4/header.hpp \
+ http/server4/mime_types.hpp \
+ http/server4/reply.hpp \
+ http/server4/request.hpp \
+ http/server4/request_parser.hpp \
+ http/server4/server.hpp \
+ icmp/icmp_header.hpp \
+ icmp/ipv4_header.hpp \
+ porthopper/protocol.hpp \
+ serialization/client.cpp \
+ serialization/server.cpp \
+ serialization/connection.hpp \
+ serialization/stock.hpp \
+ services/basic_logger.hpp \
+ services/logger.hpp \
+ services/logger_service.hpp \
+ socks4/socks4.hpp \
+ ssl/README \
+ ssl/ca.pem \
+ ssl/server.pem \
+ ssl/dh2048.pem \
+ timers/tick_count_timer.cpp
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
diff --git a/3rdparty/asio/src/examples/cpp03/allocation/.gitignore b/3rdparty/asio/src/examples/cpp03/allocation/.gitignore
new file mode 100644
index 00000000000..180ba886e58
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/allocation/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/allocation/server.cpp b/3rdparty/asio/src/examples/cpp03/allocation/server.cpp
new file mode 100644
index 00000000000..e26eb564918
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/allocation/server.cpp
@@ -0,0 +1,238 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/aligned_storage.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+// Class to manage the memory to be used for handler-based custom allocation.
+// It contains a single block of memory which may be returned for allocation
+// requests. If the memory is in use when an allocation request is made, the
+// allocator delegates allocation to the global heap.
+class handler_allocator
+ : private boost::noncopyable
+{
+public:
+ handler_allocator()
+ : in_use_(false)
+ {
+ }
+
+ void* allocate(std::size_t size)
+ {
+ if (!in_use_ && size < storage_.size)
+ {
+ in_use_ = true;
+ return storage_.address();
+ }
+ else
+ {
+ return ::operator new(size);
+ }
+ }
+
+ void deallocate(void* pointer)
+ {
+ if (pointer == storage_.address())
+ {
+ in_use_ = false;
+ }
+ else
+ {
+ ::operator delete(pointer);
+ }
+ }
+
+private:
+ // Storage space used for handler-based custom memory allocation.
+ boost::aligned_storage<1024> storage_;
+
+ // Whether the handler-based custom allocation storage has been used.
+ bool in_use_;
+};
+
+// Wrapper class template for handler objects to allow handler memory
+// allocation to be customised. Calls to operator() are forwarded to the
+// encapsulated handler.
+template <typename Handler>
+class custom_alloc_handler
+{
+public:
+ custom_alloc_handler(handler_allocator& a, Handler h)
+ : allocator_(a),
+ handler_(h)
+ {
+ }
+
+ template <typename Arg1>
+ void operator()(Arg1 arg1)
+ {
+ handler_(arg1);
+ }
+
+ template <typename Arg1, typename Arg2>
+ void operator()(Arg1 arg1, Arg2 arg2)
+ {
+ handler_(arg1, arg2);
+ }
+
+ friend void* asio_handler_allocate(std::size_t size,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ return this_handler->allocator_.allocate(size);
+ }
+
+ friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ this_handler->allocator_.deallocate(pointer);
+ }
+
+private:
+ handler_allocator& allocator_;
+ Handler handler_;
+};
+
+// Helper function to wrap a handler object to add custom allocation.
+template <typename Handler>
+inline custom_alloc_handler<Handler> make_custom_alloc_handler(
+ handler_allocator& a, Handler h)
+{
+ return custom_alloc_handler<Handler>(a, h);
+}
+
+class session
+ : public boost::enable_shared_from_this<session>
+{
+public:
+ session(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ socket_.async_read_some(asio::buffer(data_),
+ make_custom_alloc_handler(allocator_,
+ boost::bind(&session::handle_read,
+ shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred)));
+ }
+
+ void handle_read(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ asio::async_write(socket_,
+ asio::buffer(data_, bytes_transferred),
+ make_custom_alloc_handler(allocator_,
+ boost::bind(&session::handle_write,
+ shared_from_this(),
+ asio::placeholders::error)));
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(asio::buffer(data_),
+ make_custom_alloc_handler(allocator_,
+ boost::bind(&session::handle_read,
+ shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred)));
+ }
+ }
+
+private:
+ // The socket used to communicate with the client.
+ tcp::socket socket_;
+
+ // Buffer used to store data received from the client.
+ boost::array<char, 1024> data_;
+
+ // The allocator to use for handler-based custom memory allocation.
+ handler_allocator allocator_;
+};
+
+typedef boost::shared_ptr<session> session_ptr;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : io_context_(io_context),
+ acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ session_ptr new_session(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session_ptr new_session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+
+ new_session.reset(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/buffers/.gitignore b/3rdparty/asio/src/examples/cpp03/buffers/.gitignore
new file mode 100644
index 00000000000..abe68c665f5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/buffers/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+reference_counted
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/buffers/reference_counted.cpp b/3rdparty/asio/src/examples/cpp03/buffers/reference_counted.cpp
new file mode 100644
index 00000000000..9f7455cdbbd
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/buffers/reference_counted.cpp
@@ -0,0 +1,131 @@
+//
+// reference_counted.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iostream>
+#include <vector>
+
+using asio::ip::tcp;
+
+// A reference-counted non-modifiable buffer class.
+class shared_const_buffer
+{
+public:
+ // Construct from a std::string.
+ explicit shared_const_buffer(const std::string& data)
+ : data_(new std::vector<char>(data.begin(), data.end())),
+ buffer_(asio::buffer(*data_))
+ {
+ }
+
+ // Implement the ConstBufferSequence requirements.
+ typedef asio::const_buffer value_type;
+ typedef const asio::const_buffer* const_iterator;
+ const asio::const_buffer* begin() const { return &buffer_; }
+ const asio::const_buffer* end() const { return &buffer_ + 1; }
+
+private:
+ boost::shared_ptr<std::vector<char> > data_;
+ asio::const_buffer buffer_;
+};
+
+class session
+ : public boost::enable_shared_from_this<session>
+{
+public:
+ session(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ using namespace std; // For time_t, time and ctime.
+ time_t now = time(0);
+ shared_const_buffer buffer(ctime(&now));
+ asio::async_write(socket_, buffer,
+ boost::bind(&session::handle_write, shared_from_this()));
+ }
+
+ void handle_write()
+ {
+ }
+
+private:
+ // The socket used to communicate with the client.
+ tcp::socket socket_;
+};
+
+typedef boost::shared_ptr<session> session_ptr;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : io_context_(io_context),
+ acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ session_ptr new_session(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session_ptr new_session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+
+ new_session.reset(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: reference_counted <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/chat/.gitignore b/3rdparty/asio/src/examples/cpp03/chat/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/chat/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/chat/chat_client.cpp b/3rdparty/asio/src/examples/cpp03/chat/chat_client.cpp
new file mode 100644
index 00000000000..9dd16145b81
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/chat/chat_client.cpp
@@ -0,0 +1,177 @@
+//
+// chat_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+#include "chat_message.hpp"
+
+using asio::ip::tcp;
+
+typedef std::deque<chat_message> chat_message_queue;
+
+class chat_client
+{
+public:
+ chat_client(asio::io_context& io_context,
+ const tcp::resolver::results_type& endpoints)
+ : io_context_(io_context),
+ socket_(io_context)
+ {
+ asio::async_connect(socket_, endpoints,
+ boost::bind(&chat_client::handle_connect, this,
+ asio::placeholders::error));
+ }
+
+ void write(const chat_message& msg)
+ {
+ asio::post(io_context_,
+ boost::bind(&chat_client::do_write, this, msg));
+ }
+
+ void close()
+ {
+ asio::post(io_context_,
+ boost::bind(&chat_client::do_close, this));
+ }
+
+private:
+
+ void handle_connect(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(&chat_client::handle_read_header, this,
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_read_header(const asio::error_code& error)
+ {
+ if (!error && read_msg_.decode_header())
+ {
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ boost::bind(&chat_client::handle_read_body, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ do_close();
+ }
+ }
+
+ void handle_read_body(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ std::cout.write(read_msg_.body(), read_msg_.body_length());
+ std::cout << "\n";
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(&chat_client::handle_read_header, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ do_close();
+ }
+ }
+
+ void do_write(chat_message msg)
+ {
+ bool write_in_progress = !write_msgs_.empty();
+ write_msgs_.push_back(msg);
+ if (!write_in_progress)
+ {
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ boost::bind(&chat_client::handle_write, this,
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ write_msgs_.pop_front();
+ if (!write_msgs_.empty())
+ {
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ boost::bind(&chat_client::handle_write, this,
+ asio::placeholders::error));
+ }
+ }
+ else
+ {
+ do_close();
+ }
+ }
+
+ void do_close()
+ {
+ socket_.close();
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::socket socket_;
+ chat_message read_msg_;
+ chat_message_queue write_msgs_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: chat_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
+
+ chat_client c(io_context, endpoints);
+
+ asio::thread t(boost::bind(&asio::io_context::run, &io_context));
+
+ char line[chat_message::max_body_length + 1];
+ while (std::cin.getline(line, chat_message::max_body_length + 1))
+ {
+ using namespace std; // For strlen and memcpy.
+ chat_message msg;
+ msg.body_length(strlen(line));
+ memcpy(msg.body(), line, msg.body_length());
+ msg.encode_header();
+ c.write(msg);
+ }
+
+ c.close();
+ t.join();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/chat/chat_message.hpp b/3rdparty/asio/src/examples/cpp03/chat/chat_message.hpp
new file mode 100644
index 00000000000..ceeef2f03f8
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/chat/chat_message.hpp
@@ -0,0 +1,93 @@
+//
+// chat_message.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 CHAT_MESSAGE_HPP
+#define CHAT_MESSAGE_HPP
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+class chat_message
+{
+public:
+ enum { header_length = 4 };
+ enum { max_body_length = 512 };
+
+ chat_message()
+ : body_length_(0)
+ {
+ }
+
+ const char* data() const
+ {
+ return data_;
+ }
+
+ char* data()
+ {
+ return data_;
+ }
+
+ size_t length() const
+ {
+ return header_length + body_length_;
+ }
+
+ const char* body() const
+ {
+ return data_ + header_length;
+ }
+
+ char* body()
+ {
+ return data_ + header_length;
+ }
+
+ size_t body_length() const
+ {
+ return body_length_;
+ }
+
+ void body_length(size_t new_length)
+ {
+ body_length_ = new_length;
+ if (body_length_ > max_body_length)
+ body_length_ = max_body_length;
+ }
+
+ bool decode_header()
+ {
+ using namespace std; // For strncat and atoi.
+ char header[header_length + 1] = "";
+ strncat(header, data_, header_length);
+ body_length_ = atoi(header);
+ if (body_length_ > max_body_length)
+ {
+ body_length_ = 0;
+ return false;
+ }
+ return true;
+ }
+
+ void encode_header()
+ {
+ using namespace std; // For sprintf and memcpy.
+ char header[header_length + 1] = "";
+ sprintf(header, "%4d", static_cast<int>(body_length_));
+ memcpy(data_, header, header_length);
+ }
+
+private:
+ char data_[header_length + max_body_length];
+ size_t body_length_;
+};
+
+#endif // CHAT_MESSAGE_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/chat/chat_server.cpp b/3rdparty/asio/src/examples/cpp03/chat/chat_server.cpp
new file mode 100644
index 00000000000..902515b3b54
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/chat/chat_server.cpp
@@ -0,0 +1,247 @@
+//
+// chat_server.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <algorithm>
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <list>
+#include <set>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "asio.hpp"
+#include "chat_message.hpp"
+
+using asio::ip::tcp;
+
+//----------------------------------------------------------------------
+
+typedef std::deque<chat_message> chat_message_queue;
+
+//----------------------------------------------------------------------
+
+class chat_participant
+{
+public:
+ virtual ~chat_participant() {}
+ virtual void deliver(const chat_message& msg) = 0;
+};
+
+typedef boost::shared_ptr<chat_participant> chat_participant_ptr;
+
+//----------------------------------------------------------------------
+
+class chat_room
+{
+public:
+ void join(chat_participant_ptr participant)
+ {
+ participants_.insert(participant);
+ std::for_each(recent_msgs_.begin(), recent_msgs_.end(),
+ boost::bind(&chat_participant::deliver, participant, _1));
+ }
+
+ void leave(chat_participant_ptr participant)
+ {
+ participants_.erase(participant);
+ }
+
+ void deliver(const chat_message& msg)
+ {
+ recent_msgs_.push_back(msg);
+ while (recent_msgs_.size() > max_recent_msgs)
+ recent_msgs_.pop_front();
+
+ std::for_each(participants_.begin(), participants_.end(),
+ boost::bind(&chat_participant::deliver, _1, boost::ref(msg)));
+ }
+
+private:
+ std::set<chat_participant_ptr> participants_;
+ enum { max_recent_msgs = 100 };
+ chat_message_queue recent_msgs_;
+};
+
+//----------------------------------------------------------------------
+
+class chat_session
+ : public chat_participant,
+ public boost::enable_shared_from_this<chat_session>
+{
+public:
+ chat_session(asio::io_context& io_context, chat_room& room)
+ : socket_(io_context),
+ room_(room)
+ {
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ room_.join(shared_from_this());
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(
+ &chat_session::handle_read_header, shared_from_this(),
+ asio::placeholders::error));
+ }
+
+ void deliver(const chat_message& msg)
+ {
+ bool write_in_progress = !write_msgs_.empty();
+ write_msgs_.push_back(msg);
+ if (!write_in_progress)
+ {
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ boost::bind(&chat_session::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_read_header(const asio::error_code& error)
+ {
+ if (!error && read_msg_.decode_header())
+ {
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ boost::bind(&chat_session::handle_read_body, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ }
+
+ void handle_read_body(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ room_.deliver(read_msg_);
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(&chat_session::handle_read_header, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ write_msgs_.pop_front();
+ if (!write_msgs_.empty())
+ {
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ boost::bind(&chat_session::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ }
+
+private:
+ tcp::socket socket_;
+ chat_room& room_;
+ chat_message read_msg_;
+ chat_message_queue write_msgs_;
+};
+
+typedef boost::shared_ptr<chat_session> chat_session_ptr;
+
+//----------------------------------------------------------------------
+
+class chat_server
+{
+public:
+ chat_server(asio::io_context& io_context,
+ const tcp::endpoint& endpoint)
+ : io_context_(io_context),
+ acceptor_(io_context, endpoint)
+ {
+ start_accept();
+ }
+
+ void start_accept()
+ {
+ chat_session_ptr new_session(new chat_session(io_context_, room_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&chat_server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(chat_session_ptr session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ session->start();
+ }
+
+ start_accept();
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::acceptor acceptor_;
+ chat_room room_;
+};
+
+typedef boost::shared_ptr<chat_server> chat_server_ptr;
+typedef std::list<chat_server_ptr> chat_server_list;
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc < 2)
+ {
+ std::cerr << "Usage: chat_server <port> [<port> ...]\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ chat_server_list servers;
+ for (int i = 1; i < argc; ++i)
+ {
+ using namespace std; // For atoi.
+ tcp::endpoint endpoint(tcp::v4(), atoi(argv[i]));
+ chat_server_ptr server(new chat_server(io_context, endpoint));
+ servers.push_back(server);
+ }
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/chat/posix_chat_client.cpp b/3rdparty/asio/src/examples/cpp03/chat/posix_chat_client.cpp
new file mode 100644
index 00000000000..91428825aad
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/chat/posix_chat_client.cpp
@@ -0,0 +1,204 @@
+//
+// posix_chat_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+#include "chat_message.hpp"
+
+#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+
+using asio::ip::tcp;
+namespace posix = asio::posix;
+
+class posix_chat_client
+{
+public:
+ posix_chat_client(asio::io_context& io_context,
+ const tcp::resolver::results_type& endpoints)
+ : socket_(io_context),
+ input_(io_context, ::dup(STDIN_FILENO)),
+ output_(io_context, ::dup(STDOUT_FILENO)),
+ input_buffer_(chat_message::max_body_length)
+ {
+ asio::async_connect(socket_, endpoints,
+ boost::bind(&posix_chat_client::handle_connect, this,
+ asio::placeholders::error));
+ }
+
+private:
+
+ void handle_connect(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Read the fixed-length header of the next message from the server.
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(&posix_chat_client::handle_read_header, this,
+ asio::placeholders::error));
+
+ // Read a line of input entered by the user.
+ asio::async_read_until(input_, input_buffer_, '\n',
+ boost::bind(&posix_chat_client::handle_read_input, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+ void handle_read_header(const asio::error_code& error)
+ {
+ if (!error && read_msg_.decode_header())
+ {
+ // Read the variable-length body of the message from the server.
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ boost::bind(&posix_chat_client::handle_read_body, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ close();
+ }
+ }
+
+ void handle_read_body(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Write out the message we just received, terminated by a newline.
+ static char eol[] = { '\n' };
+ boost::array<asio::const_buffer, 2> buffers = {{
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ asio::buffer(eol) }};
+ asio::async_write(output_, buffers,
+ boost::bind(&posix_chat_client::handle_write_output, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ close();
+ }
+ }
+
+ void handle_write_output(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Read the fixed-length header of the next message from the server.
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ boost::bind(&posix_chat_client::handle_read_header, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ close();
+ }
+ }
+
+ void handle_read_input(const asio::error_code& error,
+ std::size_t length)
+ {
+ if (!error)
+ {
+ // Write the message (minus the newline) to the server.
+ write_msg_.body_length(length - 1);
+ input_buffer_.sgetn(write_msg_.body(), length - 1);
+ input_buffer_.consume(1); // Remove newline from input.
+ write_msg_.encode_header();
+ asio::async_write(socket_,
+ asio::buffer(write_msg_.data(), write_msg_.length()),
+ boost::bind(&posix_chat_client::handle_write, this,
+ asio::placeholders::error));
+ }
+ else if (error == asio::error::not_found)
+ {
+ // Didn't get a newline. Send whatever we have.
+ write_msg_.body_length(input_buffer_.size());
+ input_buffer_.sgetn(write_msg_.body(), input_buffer_.size());
+ write_msg_.encode_header();
+ asio::async_write(socket_,
+ asio::buffer(write_msg_.data(), write_msg_.length()),
+ boost::bind(&posix_chat_client::handle_write, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ close();
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ // Read a line of input entered by the user.
+ asio::async_read_until(input_, input_buffer_, '\n',
+ boost::bind(&posix_chat_client::handle_read_input, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ close();
+ }
+ }
+
+ void close()
+ {
+ // Cancel all outstanding asynchronous operations.
+ socket_.close();
+ input_.close();
+ output_.close();
+ }
+
+private:
+ tcp::socket socket_;
+ posix::stream_descriptor input_;
+ posix::stream_descriptor output_;
+ chat_message read_msg_;
+ chat_message write_msg_;
+ asio::streambuf input_buffer_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: posix_chat_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
+
+ posix_chat_client c(io_context, endpoints);
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
+
+#else // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+int main() {}
+#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
diff --git a/3rdparty/asio/src/examples/cpp03/echo/.gitignore b/3rdparty/asio/src/examples/cpp03/echo/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp
new file mode 100644
index 00000000000..c26136e89b5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp
@@ -0,0 +1,137 @@
+//
+// async_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+class session
+{
+public:
+ session(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+private:
+ void handle_read(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ asio::async_write(socket_,
+ asio::buffer(data_, bytes_transferred),
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+ tcp::socket socket_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : io_context_(io_context),
+ acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ session* new_session = new session(io_context_);
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session* new_session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+ else
+ {
+ delete new_session;
+ }
+
+ start_accept();
+ }
+
+ asio::io_context& io_context_;
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp
new file mode 100644
index 00000000000..851c46b0803
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp
@@ -0,0 +1,92 @@
+//
+// async_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : socket_(io_context, udp::endpoint(udp::v4(), port))
+ {
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ boost::bind(&server::handle_receive_from, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+ void handle_receive_from(const asio::error_code& error,
+ size_t bytes_recvd)
+ {
+ if (!error && bytes_recvd > 0)
+ {
+ socket_.async_send_to(
+ asio::buffer(data_, bytes_recvd), sender_endpoint_,
+ boost::bind(&server::handle_send_to, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ boost::bind(&server::handle_receive_from, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+ void handle_send_to(const asio::error_code& /*error*/,
+ size_t /*bytes_sent*/)
+ {
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ boost::bind(&server::handle_receive_from, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+private:
+ udp::socket socket_;
+ udp::endpoint sender_endpoint_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp b/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp
new file mode 100644
index 00000000000..224b9dbb1b2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp
@@ -0,0 +1,59 @@
+//
+// blocking_tcp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints =
+ resolver.resolve(tcp::v4(), argv[1], argv[2]);
+
+ tcp::socket s(io_context);
+ asio::connect(s, endpoints);
+
+ using namespace std; // For strlen.
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = strlen(request);
+ asio::write(s, asio::buffer(request, request_length));
+
+ char reply[max_length];
+ size_t reply_length = asio::read(s,
+ asio::buffer(reply, request_length));
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp
new file mode 100644
index 00000000000..163dc2a392c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp
@@ -0,0 +1,79 @@
+//
+// blocking_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind.hpp>
+#include <boost/smart_ptr.hpp>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+const int max_length = 1024;
+
+typedef boost::shared_ptr<tcp::socket> socket_ptr;
+
+void session(socket_ptr sock)
+{
+ try
+ {
+ for (;;)
+ {
+ char data[max_length];
+
+ asio::error_code error;
+ size_t length = sock->read_some(asio::buffer(data), error);
+ if (error == asio::error::eof)
+ break; // Connection closed cleanly by peer.
+ else if (error)
+ throw asio::system_error(error); // Some other error.
+
+ asio::write(*sock, asio::buffer(data, length));
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception in thread: " << e.what() << "\n";
+ }
+}
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
+ for (;;)
+ {
+ socket_ptr sock(new tcp::socket(io_context));
+ a.accept(*sock);
+ asio::thread t(boost::bind(session, sock));
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server(io_context, atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp b/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp
new file mode 100644
index 00000000000..ee90081b7ea
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp
@@ -0,0 +1,59 @@
+//
+// blocking_udp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_udp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ udp::socket s(io_context, udp::endpoint(udp::v4(), 0));
+
+ udp::resolver resolver(io_context);
+ udp::resolver::results_type endpoints =
+ resolver.resolve(udp::v4(), argv[1], argv[2]);
+
+ using namespace std; // For strlen.
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = strlen(request);
+ s.send_to(asio::buffer(request, request_length), *endpoints.begin());
+
+ char reply[max_length];
+ udp::endpoint sender_endpoint;
+ size_t reply_length = s.receive_from(
+ asio::buffer(reply, max_length), sender_endpoint);
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp
new file mode 100644
index 00000000000..3cc364c20b5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp
@@ -0,0 +1,53 @@
+//
+// blocking_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ udp::socket sock(io_context, udp::endpoint(udp::v4(), port));
+ for (;;)
+ {
+ char data[max_length];
+ udp::endpoint sender_endpoint;
+ size_t length = sock.receive_from(
+ asio::buffer(data, max_length), sender_endpoint);
+ sock.send_to(asio::buffer(data, length), sender_endpoint);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server(io_context, atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/fork/.gitignore b/3rdparty/asio/src/examples/cpp03/fork/.gitignore
new file mode 100644
index 00000000000..6b565fe313a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/fork/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+daemon
+process_per_connection
diff --git a/3rdparty/asio/src/examples/cpp03/fork/daemon.cpp b/3rdparty/asio/src/examples/cpp03/fork/daemon.cpp
new file mode 100644
index 00000000000..06eef3d6b49
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/fork/daemon.cpp
@@ -0,0 +1,189 @@
+//
+// daemon.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/io_context.hpp>
+#include <asio/ip/udp.hpp>
+#include <asio/signal_set.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <ctime>
+#include <iostream>
+#include <syslog.h>
+#include <unistd.h>
+
+using asio::ip::udp;
+
+class udp_daytime_server
+{
+public:
+ udp_daytime_server(asio::io_context& io_context)
+ : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ {
+ start_receive();
+ }
+
+private:
+ void start_receive()
+ {
+ socket_.async_receive_from(
+ asio::buffer(recv_buffer_), remote_endpoint_,
+ boost::bind(&udp_daytime_server::handle_receive, this, _1));
+ }
+
+ void handle_receive(const asio::error_code& ec)
+ {
+ if (!ec || ec == asio::error::message_size)
+ {
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ std::string message = ctime(&now);
+
+ asio::error_code ignored_ec;
+ socket_.send_to(asio::buffer(message),
+ remote_endpoint_, 0, ignored_ec);
+ }
+
+ start_receive();
+ }
+
+ udp::socket socket_;
+ udp::endpoint remote_endpoint_;
+ boost::array<char, 1> recv_buffer_;
+};
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ // Initialise the server before becoming a daemon. If the process is
+ // started from a shell, this means any errors will be reported back to the
+ // user.
+ udp_daytime_server server(io_context);
+
+ // Register signal handlers so that the daemon may be shut down. You may
+ // also want to register for other signals, such as SIGHUP to trigger a
+ // re-read of a configuration file.
+ asio::signal_set signals(io_context, SIGINT, SIGTERM);
+ signals.async_wait(
+ boost::bind(&asio::io_context::stop, &io_context));
+
+ // Inform the io_context that we are about to become a daemon. The
+ // io_context cleans up any internal resources, such as threads, that may
+ // interfere with forking.
+ io_context.notify_fork(asio::io_context::fork_prepare);
+
+ // Fork the process and have the parent exit. If the process was started
+ // from a shell, this returns control to the user. Forking a new process is
+ // also a prerequisite for the subsequent call to setsid().
+ if (pid_t pid = fork())
+ {
+ if (pid > 0)
+ {
+ // We're in the parent process and need to exit.
+ //
+ // When the exit() function is used, the program terminates without
+ // invoking local variables' destructors. Only global variables are
+ // destroyed. As the io_context object is a local variable, this means
+ // we do not have to call:
+ //
+ // io_context.notify_fork(asio::io_context::fork_parent);
+ //
+ // However, this line should be added before each call to exit() if
+ // using a global io_context object. An additional call:
+ //
+ // io_context.notify_fork(asio::io_context::fork_prepare);
+ //
+ // should also precede the second fork().
+ exit(0);
+ }
+ else
+ {
+ syslog(LOG_ERR | LOG_USER, "First fork failed: %m");
+ return 1;
+ }
+ }
+
+ // Make the process a new session leader. This detaches it from the
+ // terminal.
+ setsid();
+
+ // A process inherits its working directory from its parent. This could be
+ // on a mounted filesystem, which means that the running daemon would
+ // prevent this filesystem from being unmounted. Changing to the root
+ // directory avoids this problem.
+ chdir("/");
+
+ // The file mode creation mask is also inherited from the parent process.
+ // We don't want to restrict the permissions on files created by the
+ // daemon, so the mask is cleared.
+ umask(0);
+
+ // A second fork ensures the process cannot acquire a controlling terminal.
+ if (pid_t pid = fork())
+ {
+ if (pid > 0)
+ {
+ exit(0);
+ }
+ else
+ {
+ syslog(LOG_ERR | LOG_USER, "Second fork failed: %m");
+ return 1;
+ }
+ }
+
+ // Close the standard streams. This decouples the daemon from the terminal
+ // that started it.
+ close(0);
+ close(1);
+ close(2);
+
+ // We don't want the daemon to have any standard input.
+ if (open("/dev/null", O_RDONLY) < 0)
+ {
+ syslog(LOG_ERR | LOG_USER, "Unable to open /dev/null: %m");
+ return 1;
+ }
+
+ // Send standard output to a log file.
+ const char* output = "/tmp/asio.daemon.out";
+ const int flags = O_WRONLY | O_CREAT | O_APPEND;
+ const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ if (open(output, flags, mode) < 0)
+ {
+ syslog(LOG_ERR | LOG_USER, "Unable to open output file %s: %m", output);
+ return 1;
+ }
+
+ // Also send standard error to the same log file.
+ if (dup(1) < 0)
+ {
+ syslog(LOG_ERR | LOG_USER, "Unable to dup output descriptor: %m");
+ return 1;
+ }
+
+ // Inform the io_context that we have finished becoming a daemon. The
+ // io_context uses this opportunity to create any internal file descriptors
+ // that need to be private to the new process.
+ io_context.notify_fork(asio::io_context::fork_child);
+
+ // The io_context can now be used normally.
+ syslog(LOG_INFO | LOG_USER, "Daemon started");
+ io_context.run();
+ syslog(LOG_INFO | LOG_USER, "Daemon stopped");
+ }
+ catch (std::exception& e)
+ {
+ syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what());
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+}
diff --git a/3rdparty/asio/src/examples/cpp03/fork/process_per_connection.cpp b/3rdparty/asio/src/examples/cpp03/fork/process_per_connection.cpp
new file mode 100644
index 00000000000..483147e9552
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/fork/process_per_connection.cpp
@@ -0,0 +1,160 @@
+//
+// process_per_connection.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/io_context.hpp>
+#include <asio/ip/tcp.hpp>
+#include <asio/signal_set.hpp>
+#include <asio/write.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+using asio::ip::tcp;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, unsigned short port)
+ : io_context_(io_context),
+ signal_(io_context, SIGCHLD),
+ acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
+ socket_(io_context)
+ {
+ start_signal_wait();
+ start_accept();
+ }
+
+private:
+ void start_signal_wait()
+ {
+ signal_.async_wait(boost::bind(&server::handle_signal_wait, this));
+ }
+
+ void handle_signal_wait()
+ {
+ // Only the parent process should check for this signal. We can determine
+ // whether we are in the parent by checking if the acceptor is still open.
+ if (acceptor_.is_open())
+ {
+ // Reap completed child processes so that we don't end up with zombies.
+ int status = 0;
+ while (waitpid(-1, &status, WNOHANG) > 0) {}
+
+ start_signal_wait();
+ }
+ }
+
+ void start_accept()
+ {
+ acceptor_.async_accept(socket_,
+ boost::bind(&server::handle_accept, this, _1));
+ }
+
+ void handle_accept(const asio::error_code& ec)
+ {
+ if (!ec)
+ {
+ // Inform the io_context that we are about to fork. The io_context cleans
+ // up any internal resources, such as threads, that may interfere with
+ // forking.
+ io_context_.notify_fork(asio::io_context::fork_prepare);
+
+ if (fork() == 0)
+ {
+ // Inform the io_context that the fork is finished and that this is the
+ // child process. The io_context uses this opportunity to create any
+ // internal file descriptors that must be private to the new process.
+ io_context_.notify_fork(asio::io_context::fork_child);
+
+ // The child won't be accepting new connections, so we can close the
+ // acceptor. It remains open in the parent.
+ acceptor_.close();
+
+ // The child process is not interested in processing the SIGCHLD signal.
+ signal_.cancel();
+
+ start_read();
+ }
+ else
+ {
+ // Inform the io_context that the fork is finished (or failed) and that
+ // this is the parent process. The io_context uses this opportunity to
+ // recreate any internal resources that were cleaned up during
+ // preparation for the fork.
+ io_context_.notify_fork(asio::io_context::fork_parent);
+
+ socket_.close();
+ start_accept();
+ }
+ }
+ else
+ {
+ std::cerr << "Accept error: " << ec.message() << std::endl;
+ start_accept();
+ }
+ }
+
+ void start_read()
+ {
+ socket_.async_read_some(asio::buffer(data_),
+ boost::bind(&server::handle_read, this, _1, _2));
+ }
+
+ void handle_read(const asio::error_code& ec, std::size_t length)
+ {
+ if (!ec)
+ start_write(length);
+ }
+
+ void start_write(std::size_t length)
+ {
+ asio::async_write(socket_, asio::buffer(data_, length),
+ boost::bind(&server::handle_write, this, _1));
+ }
+
+ void handle_write(const asio::error_code& ec)
+ {
+ if (!ec)
+ start_read();
+ }
+
+ asio::io_context& io_context_;
+ asio::signal_set signal_;
+ tcp::acceptor acceptor_;
+ tcp::socket socket_;
+ boost::array<char, 1024> data_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: process_per_connection <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/client/.gitignore b/3rdparty/asio/src/examples/cpp03/http/client/.gitignore
new file mode 100644
index 00000000000..e80f510d76c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/client/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/http/client/async_client.cpp b/3rdparty/asio/src/examples/cpp03/http/client/async_client.cpp
new file mode 100644
index 00000000000..83dcc36d53a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/client/async_client.cpp
@@ -0,0 +1,204 @@
+//
+// async_client.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+
+using asio::ip::tcp;
+
+class client
+{
+public:
+ client(asio::io_context& io_context,
+ const std::string& server, const std::string& path)
+ : resolver_(io_context),
+ socket_(io_context)
+ {
+ // Form the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ std::ostream request_stream(&request_);
+ request_stream << "GET " << path << " HTTP/1.0\r\n";
+ request_stream << "Host: " << server << "\r\n";
+ request_stream << "Accept: */*\r\n";
+ request_stream << "Connection: close\r\n\r\n";
+
+ // Start an asynchronous resolve to translate the server and service names
+ // into a list of endpoints.
+ resolver_.async_resolve(server, "http",
+ boost::bind(&client::handle_resolve, this,
+ asio::placeholders::error,
+ asio::placeholders::results));
+ }
+
+private:
+ void handle_resolve(const asio::error_code& err,
+ const tcp::resolver::results_type& endpoints)
+ {
+ if (!err)
+ {
+ // Attempt a connection to each endpoint in the list until we
+ // successfully establish a connection.
+ asio::async_connect(socket_, endpoints,
+ boost::bind(&client::handle_connect, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Error: " << err.message() << "\n";
+ }
+ }
+
+ void handle_connect(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ // The connection was successful. Send the request.
+ asio::async_write(socket_, request_,
+ boost::bind(&client::handle_write_request, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Error: " << err.message() << "\n";
+ }
+ }
+
+ void handle_write_request(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ // Read the response status line. The response_ streambuf will
+ // automatically grow to accommodate the entire line. The growth may be
+ // limited by passing a maximum size to the streambuf constructor.
+ asio::async_read_until(socket_, response_, "\r\n",
+ boost::bind(&client::handle_read_status_line, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Error: " << err.message() << "\n";
+ }
+ }
+
+ void handle_read_status_line(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ // Check that response is OK.
+ std::istream response_stream(&response_);
+ std::string http_version;
+ response_stream >> http_version;
+ unsigned int status_code;
+ response_stream >> status_code;
+ std::string status_message;
+ std::getline(response_stream, status_message);
+ if (!response_stream || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ return;
+ }
+ if (status_code != 200)
+ {
+ std::cout << "Response returned with status code ";
+ std::cout << status_code << "\n";
+ return;
+ }
+
+ // Read the response headers, which are terminated by a blank line.
+ asio::async_read_until(socket_, response_, "\r\n\r\n",
+ boost::bind(&client::handle_read_headers, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Error: " << err << "\n";
+ }
+ }
+
+ void handle_read_headers(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ // Process the response headers.
+ std::istream response_stream(&response_);
+ std::string header;
+ while (std::getline(response_stream, header) && header != "\r")
+ std::cout << header << "\n";
+ std::cout << "\n";
+
+ // Write whatever content we already have to output.
+ if (response_.size() > 0)
+ std::cout << &response_;
+
+ // Start reading remaining data until EOF.
+ asio::async_read(socket_, response_,
+ asio::transfer_at_least(1),
+ boost::bind(&client::handle_read_content, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Error: " << err << "\n";
+ }
+ }
+
+ void handle_read_content(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ // Write all of the data that has been read so far.
+ std::cout << &response_;
+
+ // Continue reading remaining data until EOF.
+ asio::async_read(socket_, response_,
+ asio::transfer_at_least(1),
+ boost::bind(&client::handle_read_content, this,
+ asio::placeholders::error));
+ }
+ else if (err != asio::error::eof)
+ {
+ std::cout << "Error: " << err << "\n";
+ }
+ }
+
+ tcp::resolver resolver_;
+ tcp::socket socket_;
+ asio::streambuf request_;
+ asio::streambuf response_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cout << "Usage: async_client <server> <path>\n";
+ std::cout << "Example:\n";
+ std::cout << " async_client www.boost.org /LICENSE_1_0.txt\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+ client c(io_context, argv[1], argv[2]);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/client/sync_client.cpp b/3rdparty/asio/src/examples/cpp03/http/client/sync_client.cpp
new file mode 100644
index 00000000000..a11b5c7c76a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/client/sync_client.cpp
@@ -0,0 +1,106 @@
+//
+// sync_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cout << "Usage: sync_client <server> <path>\n";
+ std::cout << "Example:\n";
+ std::cout << " sync_client www.boost.org /LICENSE_1_0.txt\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ // Get a list of endpoints corresponding to the server name.
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints = resolver.resolve(argv[1], "http");
+
+ // Try each endpoint until we successfully establish a connection.
+ tcp::socket socket(io_context);
+ asio::connect(socket, endpoints);
+
+ // Form the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ asio::streambuf request;
+ std::ostream request_stream(&request);
+ request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";
+ request_stream << "Host: " << argv[1] << "\r\n";
+ request_stream << "Accept: */*\r\n";
+ request_stream << "Connection: close\r\n\r\n";
+
+ // Send the request.
+ asio::write(socket, request);
+
+ // Read the response status line. The response streambuf will automatically
+ // grow to accommodate the entire line. The growth may be limited by passing
+ // a maximum size to the streambuf constructor.
+ asio::streambuf response;
+ asio::read_until(socket, response, "\r\n");
+
+ // Check that response is OK.
+ std::istream response_stream(&response);
+ std::string http_version;
+ response_stream >> http_version;
+ unsigned int status_code;
+ response_stream >> status_code;
+ std::string status_message;
+ std::getline(response_stream, status_message);
+ if (!response_stream || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ return 1;
+ }
+ if (status_code != 200)
+ {
+ std::cout << "Response returned with status code " << status_code << "\n";
+ return 1;
+ }
+
+ // Read the response headers, which are terminated by a blank line.
+ asio::read_until(socket, response, "\r\n\r\n");
+
+ // Process the response headers.
+ std::string header;
+ while (std::getline(response_stream, header) && header != "\r")
+ std::cout << header << "\n";
+ std::cout << "\n";
+
+ // Write whatever content we already have to output.
+ if (response.size() > 0)
+ std::cout << &response;
+
+ // Read until EOF, writing data to output as we go.
+ asio::error_code error;
+ while (asio::read(socket, response,
+ asio::transfer_at_least(1), error))
+ std::cout << &response;
+ if (error != asio::error::eof)
+ throw asio::system_error(error);
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/doc_root/data_1K.html b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_1K.html
new file mode 100644
index 00000000000..1372c4dd177
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_1K.html
@@ -0,0 +1,28 @@
+<!--
+Copyright (c) 2003-2016 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)
+-->
+
+<html>
+<body>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the<br/>
+</body>
+</html>
+
+<!-- boostinspect:nounlinked -->
diff --git a/3rdparty/asio/src/examples/cpp03/http/doc_root/data_2K.html b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_2K.html
new file mode 100644
index 00000000000..686ce52b0a0
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_2K.html
@@ -0,0 +1,49 @@
+<!--
+Copyright (c) 2003-2016 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)
+-->
+
+<html>
+<body>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps ove<br/>
+</body>
+</html>
+
+<!-- boostinspect:nounlinked -->
diff --git a/3rdparty/asio/src/examples/cpp03/http/doc_root/data_4K.html b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_4K.html
new file mode 100644
index 00000000000..f5db0a2bc00
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_4K.html
@@ -0,0 +1,91 @@
+<!--
+Copyright (c) 2003-2016 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)
+-->
+
+<html>
+<body>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox<br/>
+</body>
+</html>
+
+<!-- boostinspect:nounlinked -->
diff --git a/3rdparty/asio/src/examples/cpp03/http/doc_root/data_8K.html b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_8K.html
new file mode 100644
index 00000000000..0d42f72886b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/doc_root/data_8K.html
@@ -0,0 +1,175 @@
+<!--
+Copyright (c) 2003-2016 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)
+-->
+
+<html>
+<body>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+The quick brown fox jumps over the lazy dog<br/>
+....
+</body>
+</html>
+
+<!-- boostinspect:nounlinked -->
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/.gitignore b/3rdparty/asio/src/examples/cpp03/http/server/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/connection.cpp b/3rdparty/asio/src/examples/cpp03/http/server/connection.cpp
new file mode 100644
index 00000000000..acbf637b453
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/connection.cpp
@@ -0,0 +1,99 @@
+//
+// connection.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection.hpp"
+#include <vector>
+#include <boost/bind.hpp>
+#include "connection_manager.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server {
+
+connection::connection(asio::io_context& io_context,
+ connection_manager& manager, request_handler& handler)
+ : socket_(io_context),
+ connection_manager_(manager),
+ request_handler_(handler)
+{
+}
+
+asio::ip::tcp::socket& connection::socket()
+{
+ return socket_;
+}
+
+void connection::start()
+{
+ socket_.async_read_some(asio::buffer(buffer_),
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+}
+
+void connection::stop()
+{
+ socket_.close();
+}
+
+void connection::handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ if (!e)
+ {
+ boost::tribool result;
+ boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
+ request_, buffer_.data(), buffer_.data() + bytes_transferred);
+
+ if (result)
+ {
+ request_handler_.handle_request(request_, reply_);
+ asio::async_write(socket_, reply_.to_buffers(),
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else if (!result)
+ {
+ reply_ = reply::stock_reply(reply::bad_request);
+ asio::async_write(socket_, reply_.to_buffers(),
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else
+ {
+ socket_.async_read_some(asio::buffer(buffer_),
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+ else if (e != asio::error::operation_aborted)
+ {
+ connection_manager_.stop(shared_from_this());
+ }
+}
+
+void connection::handle_write(const asio::error_code& e)
+{
+ if (!e)
+ {
+ // Initiate graceful connection closure.
+ asio::error_code ignored_ec;
+ socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec);
+ }
+
+ if (e != asio::error::operation_aborted)
+ {
+ connection_manager_.stop(shared_from_this());
+ }
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/connection.hpp b/3rdparty/asio/src/examples/cpp03/http/server/connection.hpp
new file mode 100644
index 00000000000..6193b486443
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/connection.hpp
@@ -0,0 +1,83 @@
+//
+// connection.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_CONNECTION_HPP
+#define HTTP_CONNECTION_HPP
+
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "reply.hpp"
+#include "request.hpp"
+#include "request_handler.hpp"
+#include "request_parser.hpp"
+
+namespace http {
+namespace server {
+
+class connection_manager;
+
+/// Represents a single connection from a client.
+class connection
+ : public boost::enable_shared_from_this<connection>,
+ private boost::noncopyable
+{
+public:
+ /// Construct a connection with the given io_context.
+ explicit connection(asio::io_context& io_context,
+ connection_manager& manager, request_handler& handler);
+
+ /// Get the socket associated with the connection.
+ asio::ip::tcp::socket& socket();
+
+ /// Start the first asynchronous operation for the connection.
+ void start();
+
+ /// Stop all asynchronous operations associated with the connection.
+ void stop();
+
+private:
+ /// Handle completion of a read operation.
+ void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred);
+
+ /// Handle completion of a write operation.
+ void handle_write(const asio::error_code& e);
+
+ /// Socket for the connection.
+ asio::ip::tcp::socket socket_;
+
+ /// The manager for this connection.
+ connection_manager& connection_manager_;
+
+ /// The handler used to process the incoming request.
+ request_handler& request_handler_;
+
+ /// Buffer for incoming data.
+ boost::array<char, 8192> buffer_;
+
+ /// The incoming request.
+ request request_;
+
+ /// The parser for the incoming request.
+ request_parser request_parser_;
+
+ /// The reply to be sent back to the client.
+ reply reply_;
+};
+
+typedef boost::shared_ptr<connection> connection_ptr;
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_CONNECTION_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.cpp b/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.cpp
new file mode 100644
index 00000000000..8fc9d8f285b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.cpp
@@ -0,0 +1,38 @@
+//
+// connection_manager.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection_manager.hpp"
+#include <algorithm>
+#include <boost/bind.hpp>
+
+namespace http {
+namespace server {
+
+void connection_manager::start(connection_ptr c)
+{
+ connections_.insert(c);
+ c->start();
+}
+
+void connection_manager::stop(connection_ptr c)
+{
+ connections_.erase(c);
+ c->stop();
+}
+
+void connection_manager::stop_all()
+{
+ std::for_each(connections_.begin(), connections_.end(),
+ boost::bind(&connection::stop, _1));
+ connections_.clear();
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.hpp b/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.hpp
new file mode 100644
index 00000000000..e67653f6a26
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/connection_manager.hpp
@@ -0,0 +1,44 @@
+//
+// connection_manager.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_CONNECTION_MANAGER_HPP
+#define HTTP_CONNECTION_MANAGER_HPP
+
+#include <set>
+#include <boost/noncopyable.hpp>
+#include "connection.hpp"
+
+namespace http {
+namespace server {
+
+/// Manages open connections so that they may be cleanly stopped when the server
+/// needs to shut down.
+class connection_manager
+ : private boost::noncopyable
+{
+public:
+ /// Add the specified connection to the manager and start it.
+ void start(connection_ptr c);
+
+ /// Stop the specified connection.
+ void stop(connection_ptr c);
+
+ /// Stop all connections.
+ void stop_all();
+
+private:
+ /// The managed connections.
+ std::set<connection_ptr> connections_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_CONNECTION_MANAGER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/header.hpp b/3rdparty/asio/src/examples/cpp03/http/server/header.hpp
new file mode 100644
index 00000000000..22e3c4a7a10
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/header.hpp
@@ -0,0 +1,28 @@
+//
+// header.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_HEADER_HPP
+#define HTTP_HEADER_HPP
+
+#include <string>
+
+namespace http {
+namespace server {
+
+struct header
+{
+ std::string name;
+ std::string value;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/main.cpp b/3rdparty/asio/src/examples/cpp03/http/server/main.cpp
new file mode 100644
index 00000000000..32d6f54dcb5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/main.cpp
@@ -0,0 +1,44 @@
+//
+// main.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include "server.hpp"
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 4)
+ {
+ std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 80 .\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 80 .\n";
+ return 1;
+ }
+
+ // Initialise the server.
+ http::server::server s(argv[1], argv[2], argv[3]);
+
+ // Run the server until stopped.
+ s.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/mime_types.cpp b/3rdparty/asio/src/examples/cpp03/http/server/mime_types.cpp
new file mode 100644
index 00000000000..80fdfe30e64
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/mime_types.cpp
@@ -0,0 +1,46 @@
+//
+// mime_types.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "mime_types.hpp"
+
+namespace http {
+namespace server {
+namespace mime_types {
+
+struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "gif", "image/gif" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "jpg", "image/jpeg" },
+ { "png", "image/png" },
+ { 0, 0 } // Marks end of list.
+};
+
+std::string extension_to_type(const std::string& extension)
+{
+ for (mapping* m = mappings; m->extension; ++m)
+ {
+ if (m->extension == extension)
+ {
+ return m->mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+} // namespace mime_types
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/mime_types.hpp b/3rdparty/asio/src/examples/cpp03/http/server/mime_types.hpp
new file mode 100644
index 00000000000..2fc0332791f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/mime_types.hpp
@@ -0,0 +1,27 @@
+//
+// mime_types.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_MIME_TYPES_HPP
+#define HTTP_MIME_TYPES_HPP
+
+#include <string>
+
+namespace http {
+namespace server {
+namespace mime_types {
+
+/// Convert a file extension into a MIME type.
+std::string extension_to_type(const std::string& extension);
+
+} // namespace mime_types
+} // namespace server
+} // namespace http
+
+#endif // HTTP_MIME_TYPES_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/reply.cpp b/3rdparty/asio/src/examples/cpp03/http/server/reply.cpp
new file mode 100644
index 00000000000..f3730d3d94d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/reply.cpp
@@ -0,0 +1,256 @@
+//
+// reply.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "reply.hpp"
+#include <string>
+#include <boost/lexical_cast.hpp>
+
+namespace http {
+namespace server {
+
+namespace status_strings {
+
+const std::string ok =
+ "HTTP/1.0 200 OK\r\n";
+const std::string created =
+ "HTTP/1.0 201 Created\r\n";
+const std::string accepted =
+ "HTTP/1.0 202 Accepted\r\n";
+const std::string no_content =
+ "HTTP/1.0 204 No Content\r\n";
+const std::string multiple_choices =
+ "HTTP/1.0 300 Multiple Choices\r\n";
+const std::string moved_permanently =
+ "HTTP/1.0 301 Moved Permanently\r\n";
+const std::string moved_temporarily =
+ "HTTP/1.0 302 Moved Temporarily\r\n";
+const std::string not_modified =
+ "HTTP/1.0 304 Not Modified\r\n";
+const std::string bad_request =
+ "HTTP/1.0 400 Bad Request\r\n";
+const std::string unauthorized =
+ "HTTP/1.0 401 Unauthorized\r\n";
+const std::string forbidden =
+ "HTTP/1.0 403 Forbidden\r\n";
+const std::string not_found =
+ "HTTP/1.0 404 Not Found\r\n";
+const std::string internal_server_error =
+ "HTTP/1.0 500 Internal Server Error\r\n";
+const std::string not_implemented =
+ "HTTP/1.0 501 Not Implemented\r\n";
+const std::string bad_gateway =
+ "HTTP/1.0 502 Bad Gateway\r\n";
+const std::string service_unavailable =
+ "HTTP/1.0 503 Service Unavailable\r\n";
+
+asio::const_buffer to_buffer(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return asio::buffer(ok);
+ case reply::created:
+ return asio::buffer(created);
+ case reply::accepted:
+ return asio::buffer(accepted);
+ case reply::no_content:
+ return asio::buffer(no_content);
+ case reply::multiple_choices:
+ return asio::buffer(multiple_choices);
+ case reply::moved_permanently:
+ return asio::buffer(moved_permanently);
+ case reply::moved_temporarily:
+ return asio::buffer(moved_temporarily);
+ case reply::not_modified:
+ return asio::buffer(not_modified);
+ case reply::bad_request:
+ return asio::buffer(bad_request);
+ case reply::unauthorized:
+ return asio::buffer(unauthorized);
+ case reply::forbidden:
+ return asio::buffer(forbidden);
+ case reply::not_found:
+ return asio::buffer(not_found);
+ case reply::internal_server_error:
+ return asio::buffer(internal_server_error);
+ case reply::not_implemented:
+ return asio::buffer(not_implemented);
+ case reply::bad_gateway:
+ return asio::buffer(bad_gateway);
+ case reply::service_unavailable:
+ return asio::buffer(service_unavailable);
+ default:
+ return asio::buffer(internal_server_error);
+ }
+}
+
+} // namespace status_strings
+
+namespace misc_strings {
+
+const char name_value_separator[] = { ':', ' ' };
+const char crlf[] = { '\r', '\n' };
+
+} // namespace misc_strings
+
+std::vector<asio::const_buffer> reply::to_buffers()
+{
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(status_strings::to_buffer(status));
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ header& h = headers[i];
+ buffers.push_back(asio::buffer(h.name));
+ buffers.push_back(asio::buffer(misc_strings::name_value_separator));
+ buffers.push_back(asio::buffer(h.value));
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ }
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ buffers.push_back(asio::buffer(content));
+ return buffers;
+}
+
+namespace stock_replies {
+
+const char ok[] = "";
+const char created[] =
+ "<html>"
+ "<head><title>Created</title></head>"
+ "<body><h1>201 Created</h1></body>"
+ "</html>";
+const char accepted[] =
+ "<html>"
+ "<head><title>Accepted</title></head>"
+ "<body><h1>202 Accepted</h1></body>"
+ "</html>";
+const char no_content[] =
+ "<html>"
+ "<head><title>No Content</title></head>"
+ "<body><h1>204 Content</h1></body>"
+ "</html>";
+const char multiple_choices[] =
+ "<html>"
+ "<head><title>Multiple Choices</title></head>"
+ "<body><h1>300 Multiple Choices</h1></body>"
+ "</html>";
+const char moved_permanently[] =
+ "<html>"
+ "<head><title>Moved Permanently</title></head>"
+ "<body><h1>301 Moved Permanently</h1></body>"
+ "</html>";
+const char moved_temporarily[] =
+ "<html>"
+ "<head><title>Moved Temporarily</title></head>"
+ "<body><h1>302 Moved Temporarily</h1></body>"
+ "</html>";
+const char not_modified[] =
+ "<html>"
+ "<head><title>Not Modified</title></head>"
+ "<body><h1>304 Not Modified</h1></body>"
+ "</html>";
+const char bad_request[] =
+ "<html>"
+ "<head><title>Bad Request</title></head>"
+ "<body><h1>400 Bad Request</h1></body>"
+ "</html>";
+const char unauthorized[] =
+ "<html>"
+ "<head><title>Unauthorized</title></head>"
+ "<body><h1>401 Unauthorized</h1></body>"
+ "</html>";
+const char forbidden[] =
+ "<html>"
+ "<head><title>Forbidden</title></head>"
+ "<body><h1>403 Forbidden</h1></body>"
+ "</html>";
+const char not_found[] =
+ "<html>"
+ "<head><title>Not Found</title></head>"
+ "<body><h1>404 Not Found</h1></body>"
+ "</html>";
+const char internal_server_error[] =
+ "<html>"
+ "<head><title>Internal Server Error</title></head>"
+ "<body><h1>500 Internal Server Error</h1></body>"
+ "</html>";
+const char not_implemented[] =
+ "<html>"
+ "<head><title>Not Implemented</title></head>"
+ "<body><h1>501 Not Implemented</h1></body>"
+ "</html>";
+const char bad_gateway[] =
+ "<html>"
+ "<head><title>Bad Gateway</title></head>"
+ "<body><h1>502 Bad Gateway</h1></body>"
+ "</html>";
+const char service_unavailable[] =
+ "<html>"
+ "<head><title>Service Unavailable</title></head>"
+ "<body><h1>503 Service Unavailable</h1></body>"
+ "</html>";
+
+std::string to_string(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return ok;
+ case reply::created:
+ return created;
+ case reply::accepted:
+ return accepted;
+ case reply::no_content:
+ return no_content;
+ case reply::multiple_choices:
+ return multiple_choices;
+ case reply::moved_permanently:
+ return moved_permanently;
+ case reply::moved_temporarily:
+ return moved_temporarily;
+ case reply::not_modified:
+ return not_modified;
+ case reply::bad_request:
+ return bad_request;
+ case reply::unauthorized:
+ return unauthorized;
+ case reply::forbidden:
+ return forbidden;
+ case reply::not_found:
+ return not_found;
+ case reply::internal_server_error:
+ return internal_server_error;
+ case reply::not_implemented:
+ return not_implemented;
+ case reply::bad_gateway:
+ return bad_gateway;
+ case reply::service_unavailable:
+ return service_unavailable;
+ default:
+ return internal_server_error;
+ }
+}
+
+} // namespace stock_replies
+
+reply reply::stock_reply(reply::status_type status)
+{
+ reply rep;
+ rep.status = status;
+ rep.content = stock_replies::to_string(status);
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = "text/html";
+ return rep;
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/reply.hpp b/3rdparty/asio/src/examples/cpp03/http/server/reply.hpp
new file mode 100644
index 00000000000..5189ac4363e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/reply.hpp
@@ -0,0 +1,64 @@
+//
+// reply.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REPLY_HPP
+#define HTTP_REPLY_HPP
+
+#include <string>
+#include <vector>
+#include <asio.hpp>
+#include "header.hpp"
+
+namespace http {
+namespace server {
+
+/// A reply to be sent to a client.
+struct reply
+{
+ /// The status of the reply.
+ enum status_type
+ {
+ ok = 200,
+ created = 201,
+ accepted = 202,
+ no_content = 204,
+ multiple_choices = 300,
+ moved_permanently = 301,
+ moved_temporarily = 302,
+ not_modified = 304,
+ bad_request = 400,
+ unauthorized = 401,
+ forbidden = 403,
+ not_found = 404,
+ internal_server_error = 500,
+ not_implemented = 501,
+ bad_gateway = 502,
+ service_unavailable = 503
+ } status;
+
+ /// The headers to be included in the reply.
+ std::vector<header> headers;
+
+ /// The content to be sent in the reply.
+ std::string content;
+
+ /// Convert the reply into a vector of buffers. The buffers do not own the
+ /// underlying memory blocks, therefore the reply object must remain valid and
+ /// not be changed until the write operation has completed.
+ std::vector<asio::const_buffer> to_buffers();
+
+ /// Get a stock reply.
+ static reply stock_reply(status_type status);
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REPLY_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/request.hpp b/3rdparty/asio/src/examples/cpp03/http/server/request.hpp
new file mode 100644
index 00000000000..129a3990b3d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/request.hpp
@@ -0,0 +1,34 @@
+//
+// request.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_HPP
+#define HTTP_REQUEST_HPP
+
+#include <string>
+#include <vector>
+#include "header.hpp"
+
+namespace http {
+namespace server {
+
+/// A request received from a client.
+struct request
+{
+ std::string method;
+ std::string uri;
+ int http_version_major;
+ int http_version_minor;
+ std::vector<header> headers;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/request_handler.cpp b/3rdparty/asio/src/examples/cpp03/http/server/request_handler.cpp
new file mode 100644
index 00000000000..1201ef109d2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/request_handler.cpp
@@ -0,0 +1,122 @@
+//
+// request_handler.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_handler.hpp"
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include "mime_types.hpp"
+#include "reply.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server {
+
+request_handler::request_handler(const std::string& doc_root)
+ : doc_root_(doc_root)
+{
+}
+
+void request_handler::handle_request(const request& req, reply& rep)
+{
+ // Decode url to path.
+ std::string request_path;
+ if (!url_decode(req.uri, request_path))
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // Request path must be absolute and not contain "..".
+ if (request_path.empty() || request_path[0] != '/'
+ || request_path.find("..") != std::string::npos)
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (request_path[request_path.size() - 1] == '/')
+ {
+ request_path += "index.html";
+ }
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = request_path.find_last_of("/");
+ std::size_t last_dot_pos = request_path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = request_path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root_ + request_path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ rep = reply::stock_reply(reply::not_found);
+ return;
+ }
+
+ // Fill out the reply to be sent to the client.
+ rep.status = reply::ok;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ rep.content.append(buf, is.gcount());
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = mime_types::extension_to_type(extension);
+}
+
+bool request_handler::url_decode(const std::string& in, std::string& out)
+{
+ out.clear();
+ out.reserve(in.size());
+ for (std::size_t i = 0; i < in.size(); ++i)
+ {
+ if (in[i] == '%')
+ {
+ if (i + 3 <= in.size())
+ {
+ int value = 0;
+ std::istringstream is(in.substr(i + 1, 2));
+ if (is >> std::hex >> value)
+ {
+ out += static_cast<char>(value);
+ i += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (in[i] == '+')
+ {
+ out += ' ';
+ }
+ else
+ {
+ out += in[i];
+ }
+ }
+ return true;
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/request_handler.hpp b/3rdparty/asio/src/examples/cpp03/http/server/request_handler.hpp
new file mode 100644
index 00000000000..56a16dd395a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/request_handler.hpp
@@ -0,0 +1,46 @@
+//
+// request_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_HANDLER_HPP
+#define HTTP_REQUEST_HANDLER_HPP
+
+#include <string>
+#include <boost/noncopyable.hpp>
+
+namespace http {
+namespace server {
+
+struct reply;
+struct request;
+
+/// The common handler for all incoming requests.
+class request_handler
+ : private boost::noncopyable
+{
+public:
+ /// Construct with a directory containing files to be served.
+ explicit request_handler(const std::string& doc_root);
+
+ /// Handle a request and produce a reply.
+ void handle_request(const request& req, reply& rep);
+
+private:
+ /// The directory containing the files to be served.
+ std::string doc_root_;
+
+ /// Perform URL-decoding on a string. Returns false if the encoding was
+ /// invalid.
+ static bool url_decode(const std::string& in, std::string& out);
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_HANDLER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/request_parser.cpp b/3rdparty/asio/src/examples/cpp03/http/server/request_parser.cpp
new file mode 100644
index 00000000000..80644eea529
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/request_parser.cpp
@@ -0,0 +1,315 @@
+//
+// request_parser.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_parser.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server {
+
+request_parser::request_parser()
+ : state_(method_start)
+{
+}
+
+void request_parser::reset()
+{
+ state_ = method_start;
+}
+
+boost::tribool request_parser::consume(request& req, char input)
+{
+ switch (state_)
+ {
+ case method_start:
+ if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = method;
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case method:
+ if (input == ' ')
+ {
+ state_ = uri;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case uri:
+ if (input == ' ')
+ {
+ state_ = http_version_h;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.uri.push_back(input);
+ return boost::indeterminate;
+ }
+ case http_version_h:
+ if (input == 'H')
+ {
+ state_ = http_version_t_1;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_1:
+ if (input == 'T')
+ {
+ state_ = http_version_t_2;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_2:
+ if (input == 'T')
+ {
+ state_ = http_version_p;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_p:
+ if (input == 'P')
+ {
+ state_ = http_version_slash;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_slash:
+ if (input == '/')
+ {
+ req.http_version_major = 0;
+ req.http_version_minor = 0;
+ state_ = http_version_major_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major_start:
+ if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ state_ = http_version_major;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major:
+ if (input == '.')
+ {
+ state_ = http_version_minor_start;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor_start:
+ if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ state_ = http_version_minor;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_1;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_1:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_line_start:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_3;
+ return boost::indeterminate;
+ }
+ else if (!req.headers.empty() && (input == ' ' || input == '\t'))
+ {
+ state_ = header_lws;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.push_back(header());
+ req.headers.back().name.push_back(input);
+ state_ = header_name;
+ return boost::indeterminate;
+ }
+ case header_lws:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (input == ' ' || input == '\t')
+ {
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = header_value;
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case header_name:
+ if (input == ':')
+ {
+ state_ = space_before_header_value;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().name.push_back(input);
+ return boost::indeterminate;
+ }
+ case space_before_header_value:
+ if (input == ' ')
+ {
+ state_ = header_value;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_value:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case expecting_newline_2:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_3:
+ return (input == '\n');
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_char(int c)
+{
+ return c >= 0 && c <= 127;
+}
+
+bool request_parser::is_ctl(int c)
+{
+ return (c >= 0 && c <= 31) || (c == 127);
+}
+
+bool request_parser::is_tspecial(int c)
+{
+ switch (c)
+ {
+ case '(': case ')': case '<': case '>': case '@':
+ case ',': case ';': case ':': case '\\': case '"':
+ case '/': case '[': case ']': case '?': case '=':
+ case '{': case '}': case ' ': case '\t':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_digit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/request_parser.hpp b/3rdparty/asio/src/examples/cpp03/http/server/request_parser.hpp
new file mode 100644
index 00000000000..d7da53cf030
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/request_parser.hpp
@@ -0,0 +1,95 @@
+//
+// request_parser.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_PARSER_HPP
+#define HTTP_REQUEST_PARSER_HPP
+
+#include <boost/logic/tribool.hpp>
+#include <boost/tuple/tuple.hpp>
+
+namespace http {
+namespace server {
+
+struct request;
+
+/// Parser for incoming requests.
+class request_parser
+{
+public:
+ /// Construct ready to parse the request method.
+ request_parser();
+
+ /// Reset to initial parser state.
+ void reset();
+
+ /// Parse some data. The tribool return value is true when a complete request
+ /// has been parsed, false if the data is invalid, indeterminate when more
+ /// data is required. The InputIterator return value indicates how much of the
+ /// input has been consumed.
+ template <typename InputIterator>
+ boost::tuple<boost::tribool, InputIterator> parse(request& req,
+ InputIterator begin, InputIterator end)
+ {
+ while (begin != end)
+ {
+ boost::tribool result = consume(req, *begin++);
+ if (result || !result)
+ return boost::make_tuple(result, begin);
+ }
+ boost::tribool result = boost::indeterminate;
+ return boost::make_tuple(result, begin);
+ }
+
+private:
+ /// Handle the next character of input.
+ boost::tribool consume(request& req, char input);
+
+ /// Check if a byte is an HTTP character.
+ static bool is_char(int c);
+
+ /// Check if a byte is an HTTP control character.
+ static bool is_ctl(int c);
+
+ /// Check if a byte is defined as an HTTP tspecial character.
+ static bool is_tspecial(int c);
+
+ /// Check if a byte is a digit.
+ static bool is_digit(int c);
+
+ /// The current state of the parser.
+ enum state
+ {
+ method_start,
+ method,
+ uri,
+ http_version_h,
+ http_version_t_1,
+ http_version_t_2,
+ http_version_p,
+ http_version_slash,
+ http_version_major_start,
+ http_version_major,
+ http_version_minor_start,
+ http_version_minor,
+ expecting_newline_1,
+ header_line_start,
+ header_lws,
+ header_name,
+ space_before_header_value,
+ header_value,
+ expecting_newline_2,
+ expecting_newline_3
+ } state_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_PARSER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/server.cpp b/3rdparty/asio/src/examples/cpp03/http/server/server.cpp
new file mode 100644
index 00000000000..89e19d08d42
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/server.cpp
@@ -0,0 +1,94 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include <boost/bind.hpp>
+#include <signal.h>
+
+namespace http {
+namespace server {
+
+server::server(const std::string& address, const std::string& port,
+ const std::string& doc_root)
+ : io_context_(),
+ signals_(io_context_),
+ acceptor_(io_context_),
+ connection_manager_(),
+ new_connection_(),
+ request_handler_(doc_root)
+{
+ // Register to handle the signals that indicate when the server should exit.
+ // It is safe to register for the same signal multiple times in a program,
+ // provided all registration for the specified signal is made through Asio.
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+#if defined(SIGQUIT)
+ signals_.add(SIGQUIT);
+#endif // defined(SIGQUIT)
+ signals_.async_wait(boost::bind(&server::handle_stop, this));
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ asio::ip::tcp::resolver resolver(io_context_);
+ asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ start_accept();
+}
+
+void server::run()
+{
+ // The io_context::run() call will block until all asynchronous operations
+ // have finished. While the server is running, there is always at least one
+ // asynchronous operation outstanding: the asynchronous accept call waiting
+ // for new incoming connections.
+ io_context_.run();
+}
+
+void server::start_accept()
+{
+ new_connection_.reset(new connection(io_context_,
+ connection_manager_, request_handler_));
+ acceptor_.async_accept(new_connection_->socket(),
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error));
+}
+
+void server::handle_accept(const asio::error_code& e)
+{
+ // Check whether the server was stopped by a signal before this completion
+ // handler had a chance to run.
+ if (!acceptor_.is_open())
+ {
+ return;
+ }
+
+ if (!e)
+ {
+ connection_manager_.start(new_connection_);
+ }
+
+ start_accept();
+}
+
+void server::handle_stop()
+{
+ // The server is stopped by cancelling all outstanding asynchronous
+ // operations. Once all operations have finished the io_context::run() call
+ // will exit.
+ acceptor_.close();
+ connection_manager_.stop_all();
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server/server.hpp b/3rdparty/asio/src/examples/cpp03/http/server/server.hpp
new file mode 100644
index 00000000000..8b0b1a23296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server/server.hpp
@@ -0,0 +1,69 @@
+//
+// server.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER_HPP
+#define HTTP_SERVER_HPP
+
+#include <asio.hpp>
+#include <string>
+#include <boost/noncopyable.hpp>
+#include "connection.hpp"
+#include "connection_manager.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server {
+
+/// The top-level class of the HTTP server.
+class server
+ : private boost::noncopyable
+{
+public:
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit server(const std::string& address, const std::string& port,
+ const std::string& doc_root);
+
+ /// Run the server's io_context loop.
+ void run();
+
+private:
+ /// Initiate an asynchronous accept operation.
+ void start_accept();
+
+ /// Handle completion of an asynchronous accept operation.
+ void handle_accept(const asio::error_code& e);
+
+ /// Handle a request to stop the server.
+ void handle_stop();
+
+ /// The io_context used to perform asynchronous operations.
+ asio::io_context io_context_;
+
+ /// The signal_set is used to register for process termination notifications.
+ asio::signal_set signals_;
+
+ /// Acceptor used to listen for incoming connections.
+ asio::ip::tcp::acceptor acceptor_;
+
+ /// The connection manager which owns all live connections.
+ connection_manager connection_manager_;
+
+ /// The next connection to be accepted.
+ connection_ptr new_connection_;
+
+ /// The handler for all incoming requests.
+ request_handler request_handler_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_SERVER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/.gitignore b/3rdparty/asio/src/examples/cpp03/http/server2/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/connection.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/connection.cpp
new file mode 100644
index 00000000000..81f4a102217
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/connection.cpp
@@ -0,0 +1,93 @@
+//
+// connection.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection.hpp"
+#include <vector>
+#include <boost/bind.hpp>
+#include "request_handler.hpp"
+
+namespace http {
+namespace server2 {
+
+connection::connection(asio::io_context& io_context,
+ request_handler& handler)
+ : socket_(io_context),
+ request_handler_(handler)
+{
+}
+
+asio::ip::tcp::socket& connection::socket()
+{
+ return socket_;
+}
+
+void connection::start()
+{
+ socket_.async_read_some(asio::buffer(buffer_),
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+}
+
+void connection::handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ if (!e)
+ {
+ boost::tribool result;
+ boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
+ request_, buffer_.data(), buffer_.data() + bytes_transferred);
+
+ if (result)
+ {
+ request_handler_.handle_request(request_, reply_);
+ asio::async_write(socket_, reply_.to_buffers(),
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else if (!result)
+ {
+ reply_ = reply::stock_reply(reply::bad_request);
+ asio::async_write(socket_, reply_.to_buffers(),
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error));
+ }
+ else
+ {
+ socket_.async_read_some(asio::buffer(buffer_),
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+ // If an error occurs then no new asynchronous operations are started. This
+ // means that all shared_ptr references to the connection object will
+ // disappear and the object will be destroyed automatically after this
+ // handler returns. The connection class's destructor closes the socket.
+}
+
+void connection::handle_write(const asio::error_code& e)
+{
+ if (!e)
+ {
+ // Initiate graceful connection closure.
+ asio::error_code ignored_ec;
+ socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec);
+ }
+
+ // No new asynchronous operations are started. This means that all shared_ptr
+ // references to the connection object will disappear and the object will be
+ // destroyed automatically after this handler returns. The connection class's
+ // destructor closes the socket.
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/connection.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/connection.hpp
new file mode 100644
index 00000000000..9c624a8a172
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/connection.hpp
@@ -0,0 +1,75 @@
+//
+// connection.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_CONNECTION_HPP
+#define HTTP_SERVER2_CONNECTION_HPP
+
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "reply.hpp"
+#include "request.hpp"
+#include "request_handler.hpp"
+#include "request_parser.hpp"
+
+namespace http {
+namespace server2 {
+
+/// Represents a single connection from a client.
+class connection
+ : public boost::enable_shared_from_this<connection>,
+ private boost::noncopyable
+{
+public:
+ /// Construct a connection with the given io_context.
+ explicit connection(asio::io_context& io_context,
+ request_handler& handler);
+
+ /// Get the socket associated with the connection.
+ asio::ip::tcp::socket& socket();
+
+ /// Start the first asynchronous operation for the connection.
+ void start();
+
+private:
+ /// Handle completion of a read operation.
+ void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred);
+
+ /// Handle completion of a write operation.
+ void handle_write(const asio::error_code& e);
+
+ /// Socket for the connection.
+ asio::ip::tcp::socket socket_;
+
+ /// The handler used to process the incoming request.
+ request_handler& request_handler_;
+
+ /// Buffer for incoming data.
+ boost::array<char, 8192> buffer_;
+
+ /// The incoming request.
+ request request_;
+
+ /// The parser for the incoming request.
+ request_parser request_parser_;
+
+ /// The reply to be sent back to the client.
+ reply reply_;
+};
+
+typedef boost::shared_ptr<connection> connection_ptr;
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_CONNECTION_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/header.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/header.hpp
new file mode 100644
index 00000000000..0e44c551409
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/header.hpp
@@ -0,0 +1,28 @@
+//
+// header.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_HEADER_HPP
+#define HTTP_SERVER2_HEADER_HPP
+
+#include <string>
+
+namespace http {
+namespace server2 {
+
+struct header
+{
+ std::string name;
+ std::string value;
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.cpp
new file mode 100644
index 00000000000..049ac988615
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.cpp
@@ -0,0 +1,69 @@
+//
+// io_context_pool.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include <stdexcept>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace http {
+namespace server2 {
+
+io_context_pool::io_context_pool(std::size_t pool_size)
+ : next_io_context_(0)
+{
+ if (pool_size == 0)
+ throw std::runtime_error("io_context_pool size is 0");
+
+ // Give all the io_contexts work to do so that their run() functions will not
+ // exit until they are explicitly stopped.
+ for (std::size_t i = 0; i < pool_size; ++i)
+ {
+ io_context_ptr io_context(new asio::io_context);
+ io_contexts_.push_back(io_context);
+ work_.push_back(asio::make_work_guard(*io_context));
+ }
+}
+
+void io_context_pool::run()
+{
+ // Create a pool of threads to run all of the io_contexts.
+ std::vector<boost::shared_ptr<asio::thread> > threads;
+ for (std::size_t i = 0; i < io_contexts_.size(); ++i)
+ {
+ boost::shared_ptr<asio::thread> thread(new asio::thread(
+ boost::bind(&asio::io_context::run, io_contexts_[i])));
+ threads.push_back(thread);
+ }
+
+ // Wait for all threads in the pool to exit.
+ for (std::size_t i = 0; i < threads.size(); ++i)
+ threads[i]->join();
+}
+
+void io_context_pool::stop()
+{
+ // Explicitly stop all io_contexts.
+ for (std::size_t i = 0; i < io_contexts_.size(); ++i)
+ io_contexts_[i]->stop();
+}
+
+asio::io_context& io_context_pool::get_io_context()
+{
+ // Use a round-robin scheme to choose the next io_context to use.
+ asio::io_context& io_context = *io_contexts_[next_io_context_];
+ ++next_io_context_;
+ if (next_io_context_ == io_contexts_.size())
+ next_io_context_ = 0;
+ return io_context;
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.hpp
new file mode 100644
index 00000000000..6a573c539f6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/io_context_pool.hpp
@@ -0,0 +1,57 @@
+//
+// io_context_pool.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_IO_SERVICE_POOL_HPP
+#define HTTP_SERVER2_IO_SERVICE_POOL_HPP
+
+#include <asio.hpp>
+#include <vector>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace http {
+namespace server2 {
+
+/// A pool of io_context objects.
+class io_context_pool
+ : private boost::noncopyable
+{
+public:
+ /// Construct the io_context pool.
+ explicit io_context_pool(std::size_t pool_size);
+
+ /// Run all io_context objects in the pool.
+ void run();
+
+ /// Stop all io_context objects in the pool.
+ void stop();
+
+ /// Get an io_context to use.
+ asio::io_context& get_io_context();
+
+private:
+ typedef boost::shared_ptr<asio::io_context> io_context_ptr;
+ typedef asio::executor_work_guard<
+ asio::io_context::executor_type> io_context_work;
+
+ /// The pool of io_contexts.
+ std::vector<io_context_ptr> io_contexts_;
+
+ /// The work that keeps the io_contexts running.
+ std::vector<io_context_work> work_;
+
+ /// The next io_context to use for a connection.
+ std::size_t next_io_context_;
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_IO_SERVICE_POOL_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/main.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/main.cpp
new file mode 100644
index 00000000000..2d224c5bac1
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/main.cpp
@@ -0,0 +1,46 @@
+//
+// main.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include "server.hpp"
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 5)
+ {
+ std::cerr << "Usage: http_server <address> <port> <threads> <doc_root>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 80 1 .\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 80 1 .\n";
+ return 1;
+ }
+
+ // Initialise the server.
+ std::size_t num_threads = boost::lexical_cast<std::size_t>(argv[3]);
+ http::server2::server s(argv[1], argv[2], argv[4], num_threads);
+
+ // Run the server until stopped.
+ s.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.cpp
new file mode 100644
index 00000000000..640f3aedc44
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.cpp
@@ -0,0 +1,46 @@
+//
+// mime_types.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "mime_types.hpp"
+
+namespace http {
+namespace server2 {
+namespace mime_types {
+
+struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "gif", "image/gif" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "jpg", "image/jpeg" },
+ { "png", "image/png" },
+ { 0, 0 } // Marks end of list.
+};
+
+std::string extension_to_type(const std::string& extension)
+{
+ for (mapping* m = mappings; m->extension; ++m)
+ {
+ if (m->extension == extension)
+ {
+ return m->mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+} // namespace mime_types
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.hpp
new file mode 100644
index 00000000000..57d1412b7b1
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/mime_types.hpp
@@ -0,0 +1,27 @@
+//
+// mime_types.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_MIME_TYPES_HPP
+#define HTTP_SERVER2_MIME_TYPES_HPP
+
+#include <string>
+
+namespace http {
+namespace server2 {
+namespace mime_types {
+
+/// Convert a file extension into a MIME type.
+std::string extension_to_type(const std::string& extension);
+
+} // namespace mime_types
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_MIME_TYPES_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/reply.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/reply.cpp
new file mode 100644
index 00000000000..958577b2ce4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/reply.cpp
@@ -0,0 +1,256 @@
+//
+// reply.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "reply.hpp"
+#include <string>
+#include <boost/lexical_cast.hpp>
+
+namespace http {
+namespace server2 {
+
+namespace status_strings {
+
+const std::string ok =
+ "HTTP/1.0 200 OK\r\n";
+const std::string created =
+ "HTTP/1.0 201 Created\r\n";
+const std::string accepted =
+ "HTTP/1.0 202 Accepted\r\n";
+const std::string no_content =
+ "HTTP/1.0 204 No Content\r\n";
+const std::string multiple_choices =
+ "HTTP/1.0 300 Multiple Choices\r\n";
+const std::string moved_permanently =
+ "HTTP/1.0 301 Moved Permanently\r\n";
+const std::string moved_temporarily =
+ "HTTP/1.0 302 Moved Temporarily\r\n";
+const std::string not_modified =
+ "HTTP/1.0 304 Not Modified\r\n";
+const std::string bad_request =
+ "HTTP/1.0 400 Bad Request\r\n";
+const std::string unauthorized =
+ "HTTP/1.0 401 Unauthorized\r\n";
+const std::string forbidden =
+ "HTTP/1.0 403 Forbidden\r\n";
+const std::string not_found =
+ "HTTP/1.0 404 Not Found\r\n";
+const std::string internal_server_error =
+ "HTTP/1.0 500 Internal Server Error\r\n";
+const std::string not_implemented =
+ "HTTP/1.0 501 Not Implemented\r\n";
+const std::string bad_gateway =
+ "HTTP/1.0 502 Bad Gateway\r\n";
+const std::string service_unavailable =
+ "HTTP/1.0 503 Service Unavailable\r\n";
+
+asio::const_buffer to_buffer(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return asio::buffer(ok);
+ case reply::created:
+ return asio::buffer(created);
+ case reply::accepted:
+ return asio::buffer(accepted);
+ case reply::no_content:
+ return asio::buffer(no_content);
+ case reply::multiple_choices:
+ return asio::buffer(multiple_choices);
+ case reply::moved_permanently:
+ return asio::buffer(moved_permanently);
+ case reply::moved_temporarily:
+ return asio::buffer(moved_temporarily);
+ case reply::not_modified:
+ return asio::buffer(not_modified);
+ case reply::bad_request:
+ return asio::buffer(bad_request);
+ case reply::unauthorized:
+ return asio::buffer(unauthorized);
+ case reply::forbidden:
+ return asio::buffer(forbidden);
+ case reply::not_found:
+ return asio::buffer(not_found);
+ case reply::internal_server_error:
+ return asio::buffer(internal_server_error);
+ case reply::not_implemented:
+ return asio::buffer(not_implemented);
+ case reply::bad_gateway:
+ return asio::buffer(bad_gateway);
+ case reply::service_unavailable:
+ return asio::buffer(service_unavailable);
+ default:
+ return asio::buffer(internal_server_error);
+ }
+}
+
+} // namespace status_strings
+
+namespace misc_strings {
+
+const char name_value_separator[] = { ':', ' ' };
+const char crlf[] = { '\r', '\n' };
+
+} // namespace misc_strings
+
+std::vector<asio::const_buffer> reply::to_buffers()
+{
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(status_strings::to_buffer(status));
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ header& h = headers[i];
+ buffers.push_back(asio::buffer(h.name));
+ buffers.push_back(asio::buffer(misc_strings::name_value_separator));
+ buffers.push_back(asio::buffer(h.value));
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ }
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ buffers.push_back(asio::buffer(content));
+ return buffers;
+}
+
+namespace stock_replies {
+
+const char ok[] = "";
+const char created[] =
+ "<html>"
+ "<head><title>Created</title></head>"
+ "<body><h1>201 Created</h1></body>"
+ "</html>";
+const char accepted[] =
+ "<html>"
+ "<head><title>Accepted</title></head>"
+ "<body><h1>202 Accepted</h1></body>"
+ "</html>";
+const char no_content[] =
+ "<html>"
+ "<head><title>No Content</title></head>"
+ "<body><h1>204 Content</h1></body>"
+ "</html>";
+const char multiple_choices[] =
+ "<html>"
+ "<head><title>Multiple Choices</title></head>"
+ "<body><h1>300 Multiple Choices</h1></body>"
+ "</html>";
+const char moved_permanently[] =
+ "<html>"
+ "<head><title>Moved Permanently</title></head>"
+ "<body><h1>301 Moved Permanently</h1></body>"
+ "</html>";
+const char moved_temporarily[] =
+ "<html>"
+ "<head><title>Moved Temporarily</title></head>"
+ "<body><h1>302 Moved Temporarily</h1></body>"
+ "</html>";
+const char not_modified[] =
+ "<html>"
+ "<head><title>Not Modified</title></head>"
+ "<body><h1>304 Not Modified</h1></body>"
+ "</html>";
+const char bad_request[] =
+ "<html>"
+ "<head><title>Bad Request</title></head>"
+ "<body><h1>400 Bad Request</h1></body>"
+ "</html>";
+const char unauthorized[] =
+ "<html>"
+ "<head><title>Unauthorized</title></head>"
+ "<body><h1>401 Unauthorized</h1></body>"
+ "</html>";
+const char forbidden[] =
+ "<html>"
+ "<head><title>Forbidden</title></head>"
+ "<body><h1>403 Forbidden</h1></body>"
+ "</html>";
+const char not_found[] =
+ "<html>"
+ "<head><title>Not Found</title></head>"
+ "<body><h1>404 Not Found</h1></body>"
+ "</html>";
+const char internal_server_error[] =
+ "<html>"
+ "<head><title>Internal Server Error</title></head>"
+ "<body><h1>500 Internal Server Error</h1></body>"
+ "</html>";
+const char not_implemented[] =
+ "<html>"
+ "<head><title>Not Implemented</title></head>"
+ "<body><h1>501 Not Implemented</h1></body>"
+ "</html>";
+const char bad_gateway[] =
+ "<html>"
+ "<head><title>Bad Gateway</title></head>"
+ "<body><h1>502 Bad Gateway</h1></body>"
+ "</html>";
+const char service_unavailable[] =
+ "<html>"
+ "<head><title>Service Unavailable</title></head>"
+ "<body><h1>503 Service Unavailable</h1></body>"
+ "</html>";
+
+std::string to_string(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return ok;
+ case reply::created:
+ return created;
+ case reply::accepted:
+ return accepted;
+ case reply::no_content:
+ return no_content;
+ case reply::multiple_choices:
+ return multiple_choices;
+ case reply::moved_permanently:
+ return moved_permanently;
+ case reply::moved_temporarily:
+ return moved_temporarily;
+ case reply::not_modified:
+ return not_modified;
+ case reply::bad_request:
+ return bad_request;
+ case reply::unauthorized:
+ return unauthorized;
+ case reply::forbidden:
+ return forbidden;
+ case reply::not_found:
+ return not_found;
+ case reply::internal_server_error:
+ return internal_server_error;
+ case reply::not_implemented:
+ return not_implemented;
+ case reply::bad_gateway:
+ return bad_gateway;
+ case reply::service_unavailable:
+ return service_unavailable;
+ default:
+ return internal_server_error;
+ }
+}
+
+} // namespace stock_replies
+
+reply reply::stock_reply(reply::status_type status)
+{
+ reply rep;
+ rep.status = status;
+ rep.content = stock_replies::to_string(status);
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = "text/html";
+ return rep;
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/reply.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/reply.hpp
new file mode 100644
index 00000000000..17f11e7dde3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/reply.hpp
@@ -0,0 +1,64 @@
+//
+// reply.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_REPLY_HPP
+#define HTTP_SERVER2_REPLY_HPP
+
+#include <string>
+#include <vector>
+#include <asio.hpp>
+#include "header.hpp"
+
+namespace http {
+namespace server2 {
+
+/// A reply to be sent to a client.
+struct reply
+{
+ /// The status of the reply.
+ enum status_type
+ {
+ ok = 200,
+ created = 201,
+ accepted = 202,
+ no_content = 204,
+ multiple_choices = 300,
+ moved_permanently = 301,
+ moved_temporarily = 302,
+ not_modified = 304,
+ bad_request = 400,
+ unauthorized = 401,
+ forbidden = 403,
+ not_found = 404,
+ internal_server_error = 500,
+ not_implemented = 501,
+ bad_gateway = 502,
+ service_unavailable = 503
+ } status;
+
+ /// The headers to be included in the reply.
+ std::vector<header> headers;
+
+ /// The content to be sent in the reply.
+ std::string content;
+
+ /// Convert the reply into a vector of buffers. The buffers do not own the
+ /// underlying memory blocks, therefore the reply object must remain valid and
+ /// not be changed until the write operation has completed.
+ std::vector<asio::const_buffer> to_buffers();
+
+ /// Get a stock reply.
+ static reply stock_reply(status_type status);
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_REPLY_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/request.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/request.hpp
new file mode 100644
index 00000000000..39070ee2f84
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/request.hpp
@@ -0,0 +1,34 @@
+//
+// request.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_REQUEST_HPP
+#define HTTP_SERVER2_REQUEST_HPP
+
+#include <string>
+#include <vector>
+#include "header.hpp"
+
+namespace http {
+namespace server2 {
+
+/// A request received from a client.
+struct request
+{
+ std::string method;
+ std::string uri;
+ int http_version_major;
+ int http_version_minor;
+ std::vector<header> headers;
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_REQUEST_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.cpp
new file mode 100644
index 00000000000..9369c107166
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.cpp
@@ -0,0 +1,122 @@
+//
+// request_handler.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_handler.hpp"
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include "mime_types.hpp"
+#include "reply.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server2 {
+
+request_handler::request_handler(const std::string& doc_root)
+ : doc_root_(doc_root)
+{
+}
+
+void request_handler::handle_request(const request& req, reply& rep)
+{
+ // Decode url to path.
+ std::string request_path;
+ if (!url_decode(req.uri, request_path))
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // Request path must be absolute and not contain "..".
+ if (request_path.empty() || request_path[0] != '/'
+ || request_path.find("..") != std::string::npos)
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (request_path[request_path.size() - 1] == '/')
+ {
+ request_path += "index.html";
+ }
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = request_path.find_last_of("/");
+ std::size_t last_dot_pos = request_path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = request_path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root_ + request_path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ rep = reply::stock_reply(reply::not_found);
+ return;
+ }
+
+ // Fill out the reply to be sent to the client.
+ rep.status = reply::ok;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ rep.content.append(buf, is.gcount());
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = mime_types::extension_to_type(extension);
+}
+
+bool request_handler::url_decode(const std::string& in, std::string& out)
+{
+ out.clear();
+ out.reserve(in.size());
+ for (std::size_t i = 0; i < in.size(); ++i)
+ {
+ if (in[i] == '%')
+ {
+ if (i + 3 <= in.size())
+ {
+ int value = 0;
+ std::istringstream is(in.substr(i + 1, 2));
+ if (is >> std::hex >> value)
+ {
+ out += static_cast<char>(value);
+ i += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (in[i] == '+')
+ {
+ out += ' ';
+ }
+ else
+ {
+ out += in[i];
+ }
+ }
+ return true;
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.hpp
new file mode 100644
index 00000000000..8d24686fa54
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/request_handler.hpp
@@ -0,0 +1,46 @@
+//
+// request_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_REQUEST_HANDLER_HPP
+#define HTTP_SERVER2_REQUEST_HANDLER_HPP
+
+#include <string>
+#include <boost/noncopyable.hpp>
+
+namespace http {
+namespace server2 {
+
+struct reply;
+struct request;
+
+/// The common handler for all incoming requests.
+class request_handler
+ : private boost::noncopyable
+{
+public:
+ /// Construct with a directory containing files to be served.
+ explicit request_handler(const std::string& doc_root);
+
+ /// Handle a request and produce a reply.
+ void handle_request(const request& req, reply& rep);
+
+private:
+ /// The directory containing the files to be served.
+ std::string doc_root_;
+
+ /// Perform URL-decoding on a string. Returns false if the encoding was
+ /// invalid.
+ static bool url_decode(const std::string& in, std::string& out);
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_REQUEST_HANDLER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.cpp
new file mode 100644
index 00000000000..ae80b20f784
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.cpp
@@ -0,0 +1,315 @@
+//
+// request_parser.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_parser.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server2 {
+
+request_parser::request_parser()
+ : state_(method_start)
+{
+}
+
+void request_parser::reset()
+{
+ state_ = method_start;
+}
+
+boost::tribool request_parser::consume(request& req, char input)
+{
+ switch (state_)
+ {
+ case method_start:
+ if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = method;
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case method:
+ if (input == ' ')
+ {
+ state_ = uri;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case uri:
+ if (input == ' ')
+ {
+ state_ = http_version_h;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.uri.push_back(input);
+ return boost::indeterminate;
+ }
+ case http_version_h:
+ if (input == 'H')
+ {
+ state_ = http_version_t_1;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_1:
+ if (input == 'T')
+ {
+ state_ = http_version_t_2;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_2:
+ if (input == 'T')
+ {
+ state_ = http_version_p;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_p:
+ if (input == 'P')
+ {
+ state_ = http_version_slash;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_slash:
+ if (input == '/')
+ {
+ req.http_version_major = 0;
+ req.http_version_minor = 0;
+ state_ = http_version_major_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major_start:
+ if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ state_ = http_version_major;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major:
+ if (input == '.')
+ {
+ state_ = http_version_minor_start;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor_start:
+ if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ state_ = http_version_minor;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_1;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_1:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_line_start:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_3;
+ return boost::indeterminate;
+ }
+ else if (!req.headers.empty() && (input == ' ' || input == '\t'))
+ {
+ state_ = header_lws;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.push_back(header());
+ req.headers.back().name.push_back(input);
+ state_ = header_name;
+ return boost::indeterminate;
+ }
+ case header_lws:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (input == ' ' || input == '\t')
+ {
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = header_value;
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case header_name:
+ if (input == ':')
+ {
+ state_ = space_before_header_value;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().name.push_back(input);
+ return boost::indeterminate;
+ }
+ case space_before_header_value:
+ if (input == ' ')
+ {
+ state_ = header_value;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_value:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case expecting_newline_2:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_3:
+ return (input == '\n');
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_char(int c)
+{
+ return c >= 0 && c <= 127;
+}
+
+bool request_parser::is_ctl(int c)
+{
+ return (c >= 0 && c <= 31) || (c == 127);
+}
+
+bool request_parser::is_tspecial(int c)
+{
+ switch (c)
+ {
+ case '(': case ')': case '<': case '>': case '@':
+ case ',': case ';': case ':': case '\\': case '"':
+ case '/': case '[': case ']': case '?': case '=':
+ case '{': case '}': case ' ': case '\t':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_digit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.hpp
new file mode 100644
index 00000000000..133a6492058
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/request_parser.hpp
@@ -0,0 +1,95 @@
+//
+// request_parser.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_REQUEST_PARSER_HPP
+#define HTTP_SERVER2_REQUEST_PARSER_HPP
+
+#include <boost/logic/tribool.hpp>
+#include <boost/tuple/tuple.hpp>
+
+namespace http {
+namespace server2 {
+
+struct request;
+
+/// Parser for incoming requests.
+class request_parser
+{
+public:
+ /// Construct ready to parse the request method.
+ request_parser();
+
+ /// Reset to initial parser state.
+ void reset();
+
+ /// Parse some data. The tribool return value is true when a complete request
+ /// has been parsed, false if the data is invalid, indeterminate when more
+ /// data is required. The InputIterator return value indicates how much of the
+ /// input has been consumed.
+ template <typename InputIterator>
+ boost::tuple<boost::tribool, InputIterator> parse(request& req,
+ InputIterator begin, InputIterator end)
+ {
+ while (begin != end)
+ {
+ boost::tribool result = consume(req, *begin++);
+ if (result || !result)
+ return boost::make_tuple(result, begin);
+ }
+ boost::tribool result = boost::indeterminate;
+ return boost::make_tuple(result, begin);
+ }
+
+private:
+ /// Handle the next character of input.
+ boost::tribool consume(request& req, char input);
+
+ /// Check if a byte is an HTTP character.
+ static bool is_char(int c);
+
+ /// Check if a byte is an HTTP control character.
+ static bool is_ctl(int c);
+
+ /// Check if a byte is defined as an HTTP tspecial character.
+ static bool is_tspecial(int c);
+
+ /// Check if a byte is a digit.
+ static bool is_digit(int c);
+
+ /// The current state of the parser.
+ enum state
+ {
+ method_start,
+ method,
+ uri,
+ http_version_h,
+ http_version_t_1,
+ http_version_t_2,
+ http_version_p,
+ http_version_slash,
+ http_version_major_start,
+ http_version_major,
+ http_version_minor_start,
+ http_version_minor,
+ expecting_newline_1,
+ header_line_start,
+ header_lws,
+ header_name,
+ space_before_header_value,
+ header_value,
+ expecting_newline_2,
+ expecting_newline_3
+ } state_;
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_REQUEST_PARSER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/server.cpp b/3rdparty/asio/src/examples/cpp03/http/server2/server.cpp
new file mode 100644
index 00000000000..75d3a48aa84
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/server.cpp
@@ -0,0 +1,77 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include <boost/bind.hpp>
+
+namespace http {
+namespace server2 {
+
+server::server(const std::string& address, const std::string& port,
+ const std::string& doc_root, std::size_t io_context_pool_size)
+ : io_context_pool_(io_context_pool_size),
+ signals_(io_context_pool_.get_io_context()),
+ acceptor_(io_context_pool_.get_io_context()),
+ new_connection_(),
+ request_handler_(doc_root)
+{
+ // Register to handle the signals that indicate when the server should exit.
+ // It is safe to register for the same signal multiple times in a program,
+ // provided all registration for the specified signal is made through Asio.
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+#if defined(SIGQUIT)
+ signals_.add(SIGQUIT);
+#endif // defined(SIGQUIT)
+ signals_.async_wait(boost::bind(&server::handle_stop, this));
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ asio::ip::tcp::resolver resolver(acceptor_.get_executor().context());
+ asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ start_accept();
+}
+
+void server::run()
+{
+ io_context_pool_.run();
+}
+
+void server::start_accept()
+{
+ new_connection_.reset(new connection(
+ io_context_pool_.get_io_context(), request_handler_));
+ acceptor_.async_accept(new_connection_->socket(),
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error));
+}
+
+void server::handle_accept(const asio::error_code& e)
+{
+ if (!e)
+ {
+ new_connection_->start();
+ }
+
+ start_accept();
+}
+
+void server::handle_stop()
+{
+ io_context_pool_.stop();
+}
+
+} // namespace server2
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server2/server.hpp b/3rdparty/asio/src/examples/cpp03/http/server2/server.hpp
new file mode 100644
index 00000000000..6a742a8220a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server2/server.hpp
@@ -0,0 +1,68 @@
+//
+// server.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER2_SERVER_HPP
+#define HTTP_SERVER2_SERVER_HPP
+
+#include <asio.hpp>
+#include <string>
+#include <vector>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include "connection.hpp"
+#include "io_context_pool.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server2 {
+
+/// The top-level class of the HTTP server.
+class server
+ : private boost::noncopyable
+{
+public:
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit server(const std::string& address, const std::string& port,
+ const std::string& doc_root, std::size_t io_context_pool_size);
+
+ /// Run the server's io_context loop.
+ void run();
+
+private:
+ /// Initiate an asynchronous accept operation.
+ void start_accept();
+
+ /// Handle completion of an asynchronous accept operation.
+ void handle_accept(const asio::error_code& e);
+
+ /// Handle a request to stop the server.
+ void handle_stop();
+
+ /// The pool of io_context objects used to perform asynchronous operations.
+ io_context_pool io_context_pool_;
+
+ /// The signal_set is used to register for process termination notifications.
+ asio::signal_set signals_;
+
+ /// Acceptor used to listen for incoming connections.
+ asio::ip::tcp::acceptor acceptor_;
+
+ /// The next connection to be accepted.
+ connection_ptr new_connection_;
+
+ /// The handler for all incoming requests.
+ request_handler request_handler_;
+};
+
+} // namespace server2
+} // namespace http
+
+#endif // HTTP_SERVER2_SERVER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/.gitignore b/3rdparty/asio/src/examples/cpp03/http/server3/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/connection.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/connection.cpp
new file mode 100644
index 00000000000..5db960a9109
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/connection.cpp
@@ -0,0 +1,98 @@
+//
+// connection.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection.hpp"
+#include <vector>
+#include <boost/bind.hpp>
+#include "request_handler.hpp"
+
+namespace http {
+namespace server3 {
+
+connection::connection(asio::io_context& io_context,
+ request_handler& handler)
+ : strand_(io_context),
+ socket_(io_context),
+ request_handler_(handler)
+{
+}
+
+asio::ip::tcp::socket& connection::socket()
+{
+ return socket_;
+}
+
+void connection::start()
+{
+ socket_.async_read_some(asio::buffer(buffer_),
+ asio::bind_executor(strand_,
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred)));
+}
+
+void connection::handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ if (!e)
+ {
+ boost::tribool result;
+ boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
+ request_, buffer_.data(), buffer_.data() + bytes_transferred);
+
+ if (result)
+ {
+ request_handler_.handle_request(request_, reply_);
+ asio::async_write(socket_, reply_.to_buffers(),
+ asio::bind_executor(strand_,
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error)));
+ }
+ else if (!result)
+ {
+ reply_ = reply::stock_reply(reply::bad_request);
+ asio::async_write(socket_, reply_.to_buffers(),
+ asio::bind_executor(strand_,
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error)));
+ }
+ else
+ {
+ socket_.async_read_some(asio::buffer(buffer_),
+ asio::bind_executor(strand_,
+ boost::bind(&connection::handle_read, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred)));
+ }
+ }
+
+ // If an error occurs then no new asynchronous operations are started. This
+ // means that all shared_ptr references to the connection object will
+ // disappear and the object will be destroyed automatically after this
+ // handler returns. The connection class's destructor closes the socket.
+}
+
+void connection::handle_write(const asio::error_code& e)
+{
+ if (!e)
+ {
+ // Initiate graceful connection closure.
+ asio::error_code ignored_ec;
+ socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec);
+ }
+
+ // No new asynchronous operations are started. This means that all shared_ptr
+ // references to the connection object will disappear and the object will be
+ // destroyed automatically after this handler returns. The connection class's
+ // destructor closes the socket.
+}
+
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/connection.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/connection.hpp
new file mode 100644
index 00000000000..2aac1a5c7ae
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/connection.hpp
@@ -0,0 +1,78 @@
+//
+// connection.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_CONNECTION_HPP
+#define HTTP_SERVER3_CONNECTION_HPP
+
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "reply.hpp"
+#include "request.hpp"
+#include "request_handler.hpp"
+#include "request_parser.hpp"
+
+namespace http {
+namespace server3 {
+
+/// Represents a single connection from a client.
+class connection
+ : public boost::enable_shared_from_this<connection>,
+ private boost::noncopyable
+{
+public:
+ /// Construct a connection with the given io_context.
+ explicit connection(asio::io_context& io_context,
+ request_handler& handler);
+
+ /// Get the socket associated with the connection.
+ asio::ip::tcp::socket& socket();
+
+ /// Start the first asynchronous operation for the connection.
+ void start();
+
+private:
+ /// Handle completion of a read operation.
+ void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred);
+
+ /// Handle completion of a write operation.
+ void handle_write(const asio::error_code& e);
+
+ /// Strand to ensure the connection's handlers are not called concurrently.
+ asio::io_context::strand strand_;
+
+ /// Socket for the connection.
+ asio::ip::tcp::socket socket_;
+
+ /// The handler used to process the incoming request.
+ request_handler& request_handler_;
+
+ /// Buffer for incoming data.
+ boost::array<char, 8192> buffer_;
+
+ /// The incoming request.
+ request request_;
+
+ /// The parser for the incoming request.
+ request_parser request_parser_;
+
+ /// The reply to be sent back to the client.
+ reply reply_;
+};
+
+typedef boost::shared_ptr<connection> connection_ptr;
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_CONNECTION_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/header.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/header.hpp
new file mode 100644
index 00000000000..207c6290784
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/header.hpp
@@ -0,0 +1,28 @@
+//
+// header.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_HEADER_HPP
+#define HTTP_SERVER3_HEADER_HPP
+
+#include <string>
+
+namespace http {
+namespace server3 {
+
+struct header
+{
+ std::string name;
+ std::string value;
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/main.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/main.cpp
new file mode 100644
index 00000000000..367efad729f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/main.cpp
@@ -0,0 +1,46 @@
+//
+// main.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include "server.hpp"
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 5)
+ {
+ std::cerr << "Usage: http_server <address> <port> <threads> <doc_root>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 80 1 .\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 80 1 .\n";
+ return 1;
+ }
+
+ // Initialise the server.
+ std::size_t num_threads = boost::lexical_cast<std::size_t>(argv[3]);
+ http::server3::server s(argv[1], argv[2], argv[4], num_threads);
+
+ // Run the server until stopped.
+ s.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.cpp
new file mode 100644
index 00000000000..0b0c66e3ce4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.cpp
@@ -0,0 +1,46 @@
+//
+// mime_types.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "mime_types.hpp"
+
+namespace http {
+namespace server3 {
+namespace mime_types {
+
+struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "gif", "image/gif" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "jpg", "image/jpeg" },
+ { "png", "image/png" },
+ { 0, 0 } // Marks end of list.
+};
+
+std::string extension_to_type(const std::string& extension)
+{
+ for (mapping* m = mappings; m->extension; ++m)
+ {
+ if (m->extension == extension)
+ {
+ return m->mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+} // namespace mime_types
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.hpp
new file mode 100644
index 00000000000..502766aa5ab
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/mime_types.hpp
@@ -0,0 +1,27 @@
+//
+// mime_types.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_MIME_TYPES_HPP
+#define HTTP_SERVER3_MIME_TYPES_HPP
+
+#include <string>
+
+namespace http {
+namespace server3 {
+namespace mime_types {
+
+/// Convert a file extension into a MIME type.
+std::string extension_to_type(const std::string& extension);
+
+} // namespace mime_types
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_MIME_TYPES_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/reply.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/reply.cpp
new file mode 100644
index 00000000000..79790a1df77
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/reply.cpp
@@ -0,0 +1,256 @@
+//
+// reply.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "reply.hpp"
+#include <string>
+#include <boost/lexical_cast.hpp>
+
+namespace http {
+namespace server3 {
+
+namespace status_strings {
+
+const std::string ok =
+ "HTTP/1.0 200 OK\r\n";
+const std::string created =
+ "HTTP/1.0 201 Created\r\n";
+const std::string accepted =
+ "HTTP/1.0 202 Accepted\r\n";
+const std::string no_content =
+ "HTTP/1.0 204 No Content\r\n";
+const std::string multiple_choices =
+ "HTTP/1.0 300 Multiple Choices\r\n";
+const std::string moved_permanently =
+ "HTTP/1.0 301 Moved Permanently\r\n";
+const std::string moved_temporarily =
+ "HTTP/1.0 302 Moved Temporarily\r\n";
+const std::string not_modified =
+ "HTTP/1.0 304 Not Modified\r\n";
+const std::string bad_request =
+ "HTTP/1.0 400 Bad Request\r\n";
+const std::string unauthorized =
+ "HTTP/1.0 401 Unauthorized\r\n";
+const std::string forbidden =
+ "HTTP/1.0 403 Forbidden\r\n";
+const std::string not_found =
+ "HTTP/1.0 404 Not Found\r\n";
+const std::string internal_server_error =
+ "HTTP/1.0 500 Internal Server Error\r\n";
+const std::string not_implemented =
+ "HTTP/1.0 501 Not Implemented\r\n";
+const std::string bad_gateway =
+ "HTTP/1.0 502 Bad Gateway\r\n";
+const std::string service_unavailable =
+ "HTTP/1.0 503 Service Unavailable\r\n";
+
+asio::const_buffer to_buffer(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return asio::buffer(ok);
+ case reply::created:
+ return asio::buffer(created);
+ case reply::accepted:
+ return asio::buffer(accepted);
+ case reply::no_content:
+ return asio::buffer(no_content);
+ case reply::multiple_choices:
+ return asio::buffer(multiple_choices);
+ case reply::moved_permanently:
+ return asio::buffer(moved_permanently);
+ case reply::moved_temporarily:
+ return asio::buffer(moved_temporarily);
+ case reply::not_modified:
+ return asio::buffer(not_modified);
+ case reply::bad_request:
+ return asio::buffer(bad_request);
+ case reply::unauthorized:
+ return asio::buffer(unauthorized);
+ case reply::forbidden:
+ return asio::buffer(forbidden);
+ case reply::not_found:
+ return asio::buffer(not_found);
+ case reply::internal_server_error:
+ return asio::buffer(internal_server_error);
+ case reply::not_implemented:
+ return asio::buffer(not_implemented);
+ case reply::bad_gateway:
+ return asio::buffer(bad_gateway);
+ case reply::service_unavailable:
+ return asio::buffer(service_unavailable);
+ default:
+ return asio::buffer(internal_server_error);
+ }
+}
+
+} // namespace status_strings
+
+namespace misc_strings {
+
+const char name_value_separator[] = { ':', ' ' };
+const char crlf[] = { '\r', '\n' };
+
+} // namespace misc_strings
+
+std::vector<asio::const_buffer> reply::to_buffers()
+{
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(status_strings::to_buffer(status));
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ header& h = headers[i];
+ buffers.push_back(asio::buffer(h.name));
+ buffers.push_back(asio::buffer(misc_strings::name_value_separator));
+ buffers.push_back(asio::buffer(h.value));
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ }
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ buffers.push_back(asio::buffer(content));
+ return buffers;
+}
+
+namespace stock_replies {
+
+const char ok[] = "";
+const char created[] =
+ "<html>"
+ "<head><title>Created</title></head>"
+ "<body><h1>201 Created</h1></body>"
+ "</html>";
+const char accepted[] =
+ "<html>"
+ "<head><title>Accepted</title></head>"
+ "<body><h1>202 Accepted</h1></body>"
+ "</html>";
+const char no_content[] =
+ "<html>"
+ "<head><title>No Content</title></head>"
+ "<body><h1>204 Content</h1></body>"
+ "</html>";
+const char multiple_choices[] =
+ "<html>"
+ "<head><title>Multiple Choices</title></head>"
+ "<body><h1>300 Multiple Choices</h1></body>"
+ "</html>";
+const char moved_permanently[] =
+ "<html>"
+ "<head><title>Moved Permanently</title></head>"
+ "<body><h1>301 Moved Permanently</h1></body>"
+ "</html>";
+const char moved_temporarily[] =
+ "<html>"
+ "<head><title>Moved Temporarily</title></head>"
+ "<body><h1>302 Moved Temporarily</h1></body>"
+ "</html>";
+const char not_modified[] =
+ "<html>"
+ "<head><title>Not Modified</title></head>"
+ "<body><h1>304 Not Modified</h1></body>"
+ "</html>";
+const char bad_request[] =
+ "<html>"
+ "<head><title>Bad Request</title></head>"
+ "<body><h1>400 Bad Request</h1></body>"
+ "</html>";
+const char unauthorized[] =
+ "<html>"
+ "<head><title>Unauthorized</title></head>"
+ "<body><h1>401 Unauthorized</h1></body>"
+ "</html>";
+const char forbidden[] =
+ "<html>"
+ "<head><title>Forbidden</title></head>"
+ "<body><h1>403 Forbidden</h1></body>"
+ "</html>";
+const char not_found[] =
+ "<html>"
+ "<head><title>Not Found</title></head>"
+ "<body><h1>404 Not Found</h1></body>"
+ "</html>";
+const char internal_server_error[] =
+ "<html>"
+ "<head><title>Internal Server Error</title></head>"
+ "<body><h1>500 Internal Server Error</h1></body>"
+ "</html>";
+const char not_implemented[] =
+ "<html>"
+ "<head><title>Not Implemented</title></head>"
+ "<body><h1>501 Not Implemented</h1></body>"
+ "</html>";
+const char bad_gateway[] =
+ "<html>"
+ "<head><title>Bad Gateway</title></head>"
+ "<body><h1>502 Bad Gateway</h1></body>"
+ "</html>";
+const char service_unavailable[] =
+ "<html>"
+ "<head><title>Service Unavailable</title></head>"
+ "<body><h1>503 Service Unavailable</h1></body>"
+ "</html>";
+
+std::string to_string(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return ok;
+ case reply::created:
+ return created;
+ case reply::accepted:
+ return accepted;
+ case reply::no_content:
+ return no_content;
+ case reply::multiple_choices:
+ return multiple_choices;
+ case reply::moved_permanently:
+ return moved_permanently;
+ case reply::moved_temporarily:
+ return moved_temporarily;
+ case reply::not_modified:
+ return not_modified;
+ case reply::bad_request:
+ return bad_request;
+ case reply::unauthorized:
+ return unauthorized;
+ case reply::forbidden:
+ return forbidden;
+ case reply::not_found:
+ return not_found;
+ case reply::internal_server_error:
+ return internal_server_error;
+ case reply::not_implemented:
+ return not_implemented;
+ case reply::bad_gateway:
+ return bad_gateway;
+ case reply::service_unavailable:
+ return service_unavailable;
+ default:
+ return internal_server_error;
+ }
+}
+
+} // namespace stock_replies
+
+reply reply::stock_reply(reply::status_type status)
+{
+ reply rep;
+ rep.status = status;
+ rep.content = stock_replies::to_string(status);
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = "text/html";
+ return rep;
+}
+
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/reply.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/reply.hpp
new file mode 100644
index 00000000000..9b057ca351d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/reply.hpp
@@ -0,0 +1,64 @@
+//
+// reply.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_REPLY_HPP
+#define HTTP_SERVER3_REPLY_HPP
+
+#include <string>
+#include <vector>
+#include <asio.hpp>
+#include "header.hpp"
+
+namespace http {
+namespace server3 {
+
+/// A reply to be sent to a client.
+struct reply
+{
+ /// The status of the reply.
+ enum status_type
+ {
+ ok = 200,
+ created = 201,
+ accepted = 202,
+ no_content = 204,
+ multiple_choices = 300,
+ moved_permanently = 301,
+ moved_temporarily = 302,
+ not_modified = 304,
+ bad_request = 400,
+ unauthorized = 401,
+ forbidden = 403,
+ not_found = 404,
+ internal_server_error = 500,
+ not_implemented = 501,
+ bad_gateway = 502,
+ service_unavailable = 503
+ } status;
+
+ /// The headers to be included in the reply.
+ std::vector<header> headers;
+
+ /// The content to be sent in the reply.
+ std::string content;
+
+ /// Convert the reply into a vector of buffers. The buffers do not own the
+ /// underlying memory blocks, therefore the reply object must remain valid and
+ /// not be changed until the write operation has completed.
+ std::vector<asio::const_buffer> to_buffers();
+
+ /// Get a stock reply.
+ static reply stock_reply(status_type status);
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_REPLY_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/request.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/request.hpp
new file mode 100644
index 00000000000..a5b34e03f8a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/request.hpp
@@ -0,0 +1,34 @@
+//
+// request.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_REQUEST_HPP
+#define HTTP_SERVER3_REQUEST_HPP
+
+#include <string>
+#include <vector>
+#include "header.hpp"
+
+namespace http {
+namespace server3 {
+
+/// A request received from a client.
+struct request
+{
+ std::string method;
+ std::string uri;
+ int http_version_major;
+ int http_version_minor;
+ std::vector<header> headers;
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_REQUEST_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.cpp
new file mode 100644
index 00000000000..9feb1cf1e3c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.cpp
@@ -0,0 +1,122 @@
+//
+// request_handler.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_handler.hpp"
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include "mime_types.hpp"
+#include "reply.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server3 {
+
+request_handler::request_handler(const std::string& doc_root)
+ : doc_root_(doc_root)
+{
+}
+
+void request_handler::handle_request(const request& req, reply& rep)
+{
+ // Decode url to path.
+ std::string request_path;
+ if (!url_decode(req.uri, request_path))
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // Request path must be absolute and not contain "..".
+ if (request_path.empty() || request_path[0] != '/'
+ || request_path.find("..") != std::string::npos)
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (request_path[request_path.size() - 1] == '/')
+ {
+ request_path += "index.html";
+ }
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = request_path.find_last_of("/");
+ std::size_t last_dot_pos = request_path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = request_path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root_ + request_path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ rep = reply::stock_reply(reply::not_found);
+ return;
+ }
+
+ // Fill out the reply to be sent to the client.
+ rep.status = reply::ok;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ rep.content.append(buf, is.gcount());
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = mime_types::extension_to_type(extension);
+}
+
+bool request_handler::url_decode(const std::string& in, std::string& out)
+{
+ out.clear();
+ out.reserve(in.size());
+ for (std::size_t i = 0; i < in.size(); ++i)
+ {
+ if (in[i] == '%')
+ {
+ if (i + 3 <= in.size())
+ {
+ int value = 0;
+ std::istringstream is(in.substr(i + 1, 2));
+ if (is >> std::hex >> value)
+ {
+ out += static_cast<char>(value);
+ i += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (in[i] == '+')
+ {
+ out += ' ';
+ }
+ else
+ {
+ out += in[i];
+ }
+ }
+ return true;
+}
+
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.hpp
new file mode 100644
index 00000000000..bb94cad0d1d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/request_handler.hpp
@@ -0,0 +1,46 @@
+//
+// request_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_REQUEST_HANDLER_HPP
+#define HTTP_SERVER3_REQUEST_HANDLER_HPP
+
+#include <string>
+#include <boost/noncopyable.hpp>
+
+namespace http {
+namespace server3 {
+
+struct reply;
+struct request;
+
+/// The common handler for all incoming requests.
+class request_handler
+ : private boost::noncopyable
+{
+public:
+ /// Construct with a directory containing files to be served.
+ explicit request_handler(const std::string& doc_root);
+
+ /// Handle a request and produce a reply.
+ void handle_request(const request& req, reply& rep);
+
+private:
+ /// The directory containing the files to be served.
+ std::string doc_root_;
+
+ /// Perform URL-decoding on a string. Returns false if the encoding was
+ /// invalid.
+ static bool url_decode(const std::string& in, std::string& out);
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_REQUEST_HANDLER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.cpp
new file mode 100644
index 00000000000..98f91286fe8
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.cpp
@@ -0,0 +1,315 @@
+//
+// request_parser.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_parser.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server3 {
+
+request_parser::request_parser()
+ : state_(method_start)
+{
+}
+
+void request_parser::reset()
+{
+ state_ = method_start;
+}
+
+boost::tribool request_parser::consume(request& req, char input)
+{
+ switch (state_)
+ {
+ case method_start:
+ if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = method;
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case method:
+ if (input == ' ')
+ {
+ state_ = uri;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.method.push_back(input);
+ return boost::indeterminate;
+ }
+ case uri:
+ if (input == ' ')
+ {
+ state_ = http_version_h;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.uri.push_back(input);
+ return boost::indeterminate;
+ }
+ case http_version_h:
+ if (input == 'H')
+ {
+ state_ = http_version_t_1;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_1:
+ if (input == 'T')
+ {
+ state_ = http_version_t_2;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_t_2:
+ if (input == 'T')
+ {
+ state_ = http_version_p;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_p:
+ if (input == 'P')
+ {
+ state_ = http_version_slash;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_slash:
+ if (input == '/')
+ {
+ req.http_version_major = 0;
+ req.http_version_minor = 0;
+ state_ = http_version_major_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major_start:
+ if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ state_ = http_version_major;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_major:
+ if (input == '.')
+ {
+ state_ = http_version_minor_start;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor_start:
+ if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ state_ = http_version_minor;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case http_version_minor:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_1;
+ return boost::indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_1:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_line_start:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_3;
+ return boost::indeterminate;
+ }
+ else if (!req.headers.empty() && (input == ' ' || input == '\t'))
+ {
+ state_ = header_lws;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.push_back(header());
+ req.headers.back().name.push_back(input);
+ state_ = header_name;
+ return boost::indeterminate;
+ }
+ case header_lws:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (input == ' ' || input == '\t')
+ {
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ state_ = header_value;
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case header_name:
+ if (input == ':')
+ {
+ state_ = space_before_header_value;
+ return boost::indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().name.push_back(input);
+ return boost::indeterminate;
+ }
+ case space_before_header_value:
+ if (input == ' ')
+ {
+ state_ = header_value;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case header_value:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return boost::indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return false;
+ }
+ else
+ {
+ req.headers.back().value.push_back(input);
+ return boost::indeterminate;
+ }
+ case expecting_newline_2:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return boost::indeterminate;
+ }
+ else
+ {
+ return false;
+ }
+ case expecting_newline_3:
+ return (input == '\n');
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_char(int c)
+{
+ return c >= 0 && c <= 127;
+}
+
+bool request_parser::is_ctl(int c)
+{
+ return (c >= 0 && c <= 31) || (c == 127);
+}
+
+bool request_parser::is_tspecial(int c)
+{
+ switch (c)
+ {
+ case '(': case ')': case '<': case '>': case '@':
+ case ',': case ';': case ':': case '\\': case '"':
+ case '/': case '[': case ']': case '?': case '=':
+ case '{': case '}': case ' ': case '\t':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_digit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.hpp
new file mode 100644
index 00000000000..b680eee037b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/request_parser.hpp
@@ -0,0 +1,95 @@
+//
+// request_parser.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_REQUEST_PARSER_HPP
+#define HTTP_SERVER3_REQUEST_PARSER_HPP
+
+#include <boost/logic/tribool.hpp>
+#include <boost/tuple/tuple.hpp>
+
+namespace http {
+namespace server3 {
+
+struct request;
+
+/// Parser for incoming requests.
+class request_parser
+{
+public:
+ /// Construct ready to parse the request method.
+ request_parser();
+
+ /// Reset to initial parser state.
+ void reset();
+
+ /// Parse some data. The tribool return value is true when a complete request
+ /// has been parsed, false if the data is invalid, indeterminate when more
+ /// data is required. The InputIterator return value indicates how much of the
+ /// input has been consumed.
+ template <typename InputIterator>
+ boost::tuple<boost::tribool, InputIterator> parse(request& req,
+ InputIterator begin, InputIterator end)
+ {
+ while (begin != end)
+ {
+ boost::tribool result = consume(req, *begin++);
+ if (result || !result)
+ return boost::make_tuple(result, begin);
+ }
+ boost::tribool result = boost::indeterminate;
+ return boost::make_tuple(result, begin);
+ }
+
+private:
+ /// Handle the next character of input.
+ boost::tribool consume(request& req, char input);
+
+ /// Check if a byte is an HTTP character.
+ static bool is_char(int c);
+
+ /// Check if a byte is an HTTP control character.
+ static bool is_ctl(int c);
+
+ /// Check if a byte is defined as an HTTP tspecial character.
+ static bool is_tspecial(int c);
+
+ /// Check if a byte is a digit.
+ static bool is_digit(int c);
+
+ /// The current state of the parser.
+ enum state
+ {
+ method_start,
+ method,
+ uri,
+ http_version_h,
+ http_version_t_1,
+ http_version_t_2,
+ http_version_p,
+ http_version_slash,
+ http_version_major_start,
+ http_version_major,
+ http_version_minor_start,
+ http_version_minor,
+ expecting_newline_1,
+ header_line_start,
+ header_lws,
+ header_name,
+ space_before_header_value,
+ header_value,
+ expecting_newline_2,
+ expecting_newline_3
+ } state_;
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_REQUEST_PARSER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/server.cpp b/3rdparty/asio/src/examples/cpp03/http/server3/server.cpp
new file mode 100644
index 00000000000..2a78bc9719e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/server.cpp
@@ -0,0 +1,89 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace http {
+namespace server3 {
+
+server::server(const std::string& address, const std::string& port,
+ const std::string& doc_root, std::size_t thread_pool_size)
+ : thread_pool_size_(thread_pool_size),
+ signals_(io_context_),
+ acceptor_(io_context_),
+ new_connection_(),
+ request_handler_(doc_root)
+{
+ // Register to handle the signals that indicate when the server should exit.
+ // It is safe to register for the same signal multiple times in a program,
+ // provided all registration for the specified signal is made through Asio.
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+#if defined(SIGQUIT)
+ signals_.add(SIGQUIT);
+#endif // defined(SIGQUIT)
+ signals_.async_wait(boost::bind(&server::handle_stop, this));
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ asio::ip::tcp::resolver resolver(io_context_);
+ asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ start_accept();
+}
+
+void server::run()
+{
+ // Create a pool of threads to run all of the io_contexts.
+ std::vector<boost::shared_ptr<asio::thread> > threads;
+ for (std::size_t i = 0; i < thread_pool_size_; ++i)
+ {
+ boost::shared_ptr<asio::thread> thread(new asio::thread(
+ boost::bind(&asio::io_context::run, &io_context_)));
+ threads.push_back(thread);
+ }
+
+ // Wait for all threads in the pool to exit.
+ for (std::size_t i = 0; i < threads.size(); ++i)
+ threads[i]->join();
+}
+
+void server::start_accept()
+{
+ new_connection_.reset(new connection(io_context_, request_handler_));
+ acceptor_.async_accept(new_connection_->socket(),
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error));
+}
+
+void server::handle_accept(const asio::error_code& e)
+{
+ if (!e)
+ {
+ new_connection_->start();
+ }
+
+ start_accept();
+}
+
+void server::handle_stop()
+{
+ io_context_.stop();
+}
+
+} // namespace server3
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server3/server.hpp b/3rdparty/asio/src/examples/cpp03/http/server3/server.hpp
new file mode 100644
index 00000000000..c58c2433f65
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server3/server.hpp
@@ -0,0 +1,70 @@
+//
+// server.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER3_SERVER_HPP
+#define HTTP_SERVER3_SERVER_HPP
+
+#include <asio.hpp>
+#include <string>
+#include <vector>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include "connection.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server3 {
+
+/// The top-level class of the HTTP server.
+class server
+ : private boost::noncopyable
+{
+public:
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit server(const std::string& address, const std::string& port,
+ const std::string& doc_root, std::size_t thread_pool_size);
+
+ /// Run the server's io_context loop.
+ void run();
+
+private:
+ /// Initiate an asynchronous accept operation.
+ void start_accept();
+
+ /// Handle completion of an asynchronous accept operation.
+ void handle_accept(const asio::error_code& e);
+
+ /// Handle a request to stop the server.
+ void handle_stop();
+
+ /// The number of threads that will call io_context::run().
+ std::size_t thread_pool_size_;
+
+ /// The io_context used to perform asynchronous operations.
+ asio::io_context io_context_;
+
+ /// The signal_set is used to register for process termination notifications.
+ asio::signal_set signals_;
+
+ /// Acceptor used to listen for incoming connections.
+ asio::ip::tcp::acceptor acceptor_;
+
+ /// The next connection to be accepted.
+ connection_ptr new_connection_;
+
+ /// The handler for all incoming requests.
+ request_handler request_handler_;
+};
+
+} // namespace server3
+} // namespace http
+
+#endif // HTTP_SERVER3_SERVER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/.gitignore b/3rdparty/asio/src/examples/cpp03/http/server4/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.cpp
new file mode 100644
index 00000000000..a4ac912b155
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.cpp
@@ -0,0 +1,122 @@
+//
+// file_handler.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "file_handler.hpp"
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include "mime_types.hpp"
+#include "reply.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server4 {
+
+file_handler::file_handler(const std::string& doc_root)
+ : doc_root_(doc_root)
+{
+}
+
+void file_handler::operator()(const request& req, reply& rep)
+{
+ // Decode url to path.
+ std::string request_path;
+ if (!url_decode(req.uri, request_path))
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // Request path must be absolute and not contain "..".
+ if (request_path.empty() || request_path[0] != '/'
+ || request_path.find("..") != std::string::npos)
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (request_path[request_path.size() - 1] == '/')
+ {
+ request_path += "index.html";
+ }
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = request_path.find_last_of("/");
+ std::size_t last_dot_pos = request_path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = request_path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root_ + request_path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ rep = reply::stock_reply(reply::not_found);
+ return;
+ }
+
+ // Fill out the reply to be sent to the client.
+ rep.status = reply::ok;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ rep.content.append(buf, is.gcount());
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = mime_types::extension_to_type(extension);
+}
+
+bool file_handler::url_decode(const std::string& in, std::string& out)
+{
+ out.clear();
+ out.reserve(in.size());
+ for (std::size_t i = 0; i < in.size(); ++i)
+ {
+ if (in[i] == '%')
+ {
+ if (i + 3 <= in.size())
+ {
+ int value = 0;
+ std::istringstream is(in.substr(i + 1, 2));
+ if (is >> std::hex >> value)
+ {
+ out += static_cast<char>(value);
+ i += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (in[i] == '+')
+ {
+ out += ' ';
+ }
+ else
+ {
+ out += in[i];
+ }
+ }
+ return true;
+}
+
+} // namespace server4
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.hpp
new file mode 100644
index 00000000000..22055dbcb1b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/file_handler.hpp
@@ -0,0 +1,44 @@
+//
+// file_handler.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_FILE_HANDLER_HPP
+#define HTTP_SERVER4_FILE_HANDLER_HPP
+
+#include <string>
+
+namespace http {
+namespace server4 {
+
+struct reply;
+struct request;
+
+/// The common handler for all incoming requests.
+class file_handler
+{
+public:
+ /// Construct with a directory containing files to be served.
+ explicit file_handler(const std::string& doc_root);
+
+ /// Handle a request and produce a reply.
+ void operator()(const request& req, reply& rep);
+
+private:
+ /// The directory containing the files to be served.
+ std::string doc_root_;
+
+ /// Perform URL-decoding on a string. Returns false if the encoding was
+ /// invalid.
+ static bool url_decode(const std::string& in, std::string& out);
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_FILE_HANDLER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/header.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/header.hpp
new file mode 100644
index 00000000000..9c9b89cca06
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/header.hpp
@@ -0,0 +1,28 @@
+//
+// header.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_HEADER_HPP
+#define HTTP_SERVER4_HEADER_HPP
+
+#include <string>
+
+namespace http {
+namespace server4 {
+
+struct header
+{
+ std::string name;
+ std::string value;
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/main.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/main.cpp
new file mode 100644
index 00000000000..0ebe535ad17
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/main.cpp
@@ -0,0 +1,58 @@
+//
+// main.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <signal.h>
+#include "server.hpp"
+#include "file_handler.hpp"
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 4)
+ {
+ std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 80 .\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 80 .\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ // Launch the initial server coroutine.
+ http::server4::server(io_context, argv[1], argv[2],
+ http::server4::file_handler(argv[3]))();
+
+ // Wait for signals indicating time to shut down.
+ asio::signal_set signals(io_context);
+ signals.add(SIGINT);
+ signals.add(SIGTERM);
+#if defined(SIGQUIT)
+ signals.add(SIGQUIT);
+#endif // defined(SIGQUIT)
+ signals.async_wait(boost::bind(
+ &asio::io_context::stop, &io_context));
+
+ // Run the server.
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.cpp
new file mode 100644
index 00000000000..903dffca59e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.cpp
@@ -0,0 +1,46 @@
+//
+// mime_types.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "mime_types.hpp"
+
+namespace http {
+namespace server4 {
+namespace mime_types {
+
+struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "gif", "image/gif" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "jpg", "image/jpeg" },
+ { "png", "image/png" },
+ { 0, 0 } // Marks end of list.
+};
+
+std::string extension_to_type(const std::string& extension)
+{
+ for (mapping* m = mappings; m->extension; ++m)
+ {
+ if (m->extension == extension)
+ {
+ return m->mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+} // namespace mime_types
+} // namespace server4
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.hpp
new file mode 100644
index 00000000000..f702c6f859b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/mime_types.hpp
@@ -0,0 +1,27 @@
+//
+// mime_types.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_MIME_TYPES_HPP
+#define HTTP_SERVER4_MIME_TYPES_HPP
+
+#include <string>
+
+namespace http {
+namespace server4 {
+namespace mime_types {
+
+/// Convert a file extension into a MIME type.
+std::string extension_to_type(const std::string& extension);
+
+} // namespace mime_types
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_MIME_TYPES_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/reply.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/reply.cpp
new file mode 100644
index 00000000000..f508a46765f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/reply.cpp
@@ -0,0 +1,256 @@
+//
+// reply.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "reply.hpp"
+#include <string>
+#include <boost/lexical_cast.hpp>
+
+namespace http {
+namespace server4 {
+
+namespace status_strings {
+
+const std::string ok =
+ "HTTP/1.0 200 OK\r\n";
+const std::string created =
+ "HTTP/1.0 201 Created\r\n";
+const std::string accepted =
+ "HTTP/1.0 202 Accepted\r\n";
+const std::string no_content =
+ "HTTP/1.0 204 No Content\r\n";
+const std::string multiple_choices =
+ "HTTP/1.0 300 Multiple Choices\r\n";
+const std::string moved_permanently =
+ "HTTP/1.0 301 Moved Permanently\r\n";
+const std::string moved_temporarily =
+ "HTTP/1.0 302 Moved Temporarily\r\n";
+const std::string not_modified =
+ "HTTP/1.0 304 Not Modified\r\n";
+const std::string bad_request =
+ "HTTP/1.0 400 Bad Request\r\n";
+const std::string unauthorized =
+ "HTTP/1.0 401 Unauthorized\r\n";
+const std::string forbidden =
+ "HTTP/1.0 403 Forbidden\r\n";
+const std::string not_found =
+ "HTTP/1.0 404 Not Found\r\n";
+const std::string internal_server_error =
+ "HTTP/1.0 500 Internal Server Error\r\n";
+const std::string not_implemented =
+ "HTTP/1.0 501 Not Implemented\r\n";
+const std::string bad_gateway =
+ "HTTP/1.0 502 Bad Gateway\r\n";
+const std::string service_unavailable =
+ "HTTP/1.0 503 Service Unavailable\r\n";
+
+asio::const_buffer to_buffer(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return asio::buffer(ok);
+ case reply::created:
+ return asio::buffer(created);
+ case reply::accepted:
+ return asio::buffer(accepted);
+ case reply::no_content:
+ return asio::buffer(no_content);
+ case reply::multiple_choices:
+ return asio::buffer(multiple_choices);
+ case reply::moved_permanently:
+ return asio::buffer(moved_permanently);
+ case reply::moved_temporarily:
+ return asio::buffer(moved_temporarily);
+ case reply::not_modified:
+ return asio::buffer(not_modified);
+ case reply::bad_request:
+ return asio::buffer(bad_request);
+ case reply::unauthorized:
+ return asio::buffer(unauthorized);
+ case reply::forbidden:
+ return asio::buffer(forbidden);
+ case reply::not_found:
+ return asio::buffer(not_found);
+ case reply::internal_server_error:
+ return asio::buffer(internal_server_error);
+ case reply::not_implemented:
+ return asio::buffer(not_implemented);
+ case reply::bad_gateway:
+ return asio::buffer(bad_gateway);
+ case reply::service_unavailable:
+ return asio::buffer(service_unavailable);
+ default:
+ return asio::buffer(internal_server_error);
+ }
+}
+
+} // namespace status_strings
+
+namespace misc_strings {
+
+const char name_value_separator[] = { ':', ' ' };
+const char crlf[] = { '\r', '\n' };
+
+} // namespace misc_strings
+
+std::vector<asio::const_buffer> reply::to_buffers()
+{
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(status_strings::to_buffer(status));
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ header& h = headers[i];
+ buffers.push_back(asio::buffer(h.name));
+ buffers.push_back(asio::buffer(misc_strings::name_value_separator));
+ buffers.push_back(asio::buffer(h.value));
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ }
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ buffers.push_back(asio::buffer(content));
+ return buffers;
+}
+
+namespace stock_replies {
+
+const char ok[] = "";
+const char created[] =
+ "<html>"
+ "<head><title>Created</title></head>"
+ "<body><h1>201 Created</h1></body>"
+ "</html>";
+const char accepted[] =
+ "<html>"
+ "<head><title>Accepted</title></head>"
+ "<body><h1>202 Accepted</h1></body>"
+ "</html>";
+const char no_content[] =
+ "<html>"
+ "<head><title>No Content</title></head>"
+ "<body><h1>204 Content</h1></body>"
+ "</html>";
+const char multiple_choices[] =
+ "<html>"
+ "<head><title>Multiple Choices</title></head>"
+ "<body><h1>300 Multiple Choices</h1></body>"
+ "</html>";
+const char moved_permanently[] =
+ "<html>"
+ "<head><title>Moved Permanently</title></head>"
+ "<body><h1>301 Moved Permanently</h1></body>"
+ "</html>";
+const char moved_temporarily[] =
+ "<html>"
+ "<head><title>Moved Temporarily</title></head>"
+ "<body><h1>302 Moved Temporarily</h1></body>"
+ "</html>";
+const char not_modified[] =
+ "<html>"
+ "<head><title>Not Modified</title></head>"
+ "<body><h1>304 Not Modified</h1></body>"
+ "</html>";
+const char bad_request[] =
+ "<html>"
+ "<head><title>Bad Request</title></head>"
+ "<body><h1>400 Bad Request</h1></body>"
+ "</html>";
+const char unauthorized[] =
+ "<html>"
+ "<head><title>Unauthorized</title></head>"
+ "<body><h1>401 Unauthorized</h1></body>"
+ "</html>";
+const char forbidden[] =
+ "<html>"
+ "<head><title>Forbidden</title></head>"
+ "<body><h1>403 Forbidden</h1></body>"
+ "</html>";
+const char not_found[] =
+ "<html>"
+ "<head><title>Not Found</title></head>"
+ "<body><h1>404 Not Found</h1></body>"
+ "</html>";
+const char internal_server_error[] =
+ "<html>"
+ "<head><title>Internal Server Error</title></head>"
+ "<body><h1>500 Internal Server Error</h1></body>"
+ "</html>";
+const char not_implemented[] =
+ "<html>"
+ "<head><title>Not Implemented</title></head>"
+ "<body><h1>501 Not Implemented</h1></body>"
+ "</html>";
+const char bad_gateway[] =
+ "<html>"
+ "<head><title>Bad Gateway</title></head>"
+ "<body><h1>502 Bad Gateway</h1></body>"
+ "</html>";
+const char service_unavailable[] =
+ "<html>"
+ "<head><title>Service Unavailable</title></head>"
+ "<body><h1>503 Service Unavailable</h1></body>"
+ "</html>";
+
+std::string to_string(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return ok;
+ case reply::created:
+ return created;
+ case reply::accepted:
+ return accepted;
+ case reply::no_content:
+ return no_content;
+ case reply::multiple_choices:
+ return multiple_choices;
+ case reply::moved_permanently:
+ return moved_permanently;
+ case reply::moved_temporarily:
+ return moved_temporarily;
+ case reply::not_modified:
+ return not_modified;
+ case reply::bad_request:
+ return bad_request;
+ case reply::unauthorized:
+ return unauthorized;
+ case reply::forbidden:
+ return forbidden;
+ case reply::not_found:
+ return not_found;
+ case reply::internal_server_error:
+ return internal_server_error;
+ case reply::not_implemented:
+ return not_implemented;
+ case reply::bad_gateway:
+ return bad_gateway;
+ case reply::service_unavailable:
+ return service_unavailable;
+ default:
+ return internal_server_error;
+ }
+}
+
+} // namespace stock_replies
+
+reply reply::stock_reply(reply::status_type status)
+{
+ reply rep;
+ rep.status = status;
+ rep.content = stock_replies::to_string(status);
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = "text/html";
+ return rep;
+}
+
+} // namespace server4
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/reply.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/reply.hpp
new file mode 100644
index 00000000000..02743a549be
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/reply.hpp
@@ -0,0 +1,64 @@
+//
+// reply.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_REPLY_HPP
+#define HTTP_SERVER4_REPLY_HPP
+
+#include <string>
+#include <vector>
+#include <asio.hpp>
+#include "header.hpp"
+
+namespace http {
+namespace server4 {
+
+/// A reply to be sent to a client.
+struct reply
+{
+ /// The status of the reply.
+ enum status_type
+ {
+ ok = 200,
+ created = 201,
+ accepted = 202,
+ no_content = 204,
+ multiple_choices = 300,
+ moved_permanently = 301,
+ moved_temporarily = 302,
+ not_modified = 304,
+ bad_request = 400,
+ unauthorized = 401,
+ forbidden = 403,
+ not_found = 404,
+ internal_server_error = 500,
+ not_implemented = 501,
+ bad_gateway = 502,
+ service_unavailable = 503
+ } status;
+
+ /// The headers to be included in the reply.
+ std::vector<header> headers;
+
+ /// The content to be sent in the reply.
+ std::string content;
+
+ /// Convert the reply into a vector of buffers. The buffers do not own the
+ /// underlying memory blocks, therefore the reply object must remain valid and
+ /// not be changed until the write operation has completed.
+ std::vector<asio::const_buffer> to_buffers();
+
+ /// Get a stock reply.
+ static reply stock_reply(status_type status);
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_REPLY_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/request.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/request.hpp
new file mode 100644
index 00000000000..43947d7f09e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/request.hpp
@@ -0,0 +1,46 @@
+//
+// request.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_REQUEST_HPP
+#define HTTP_SERVER4_REQUEST_HPP
+
+#include <string>
+#include <vector>
+#include "header.hpp"
+
+namespace http {
+namespace server4 {
+
+/// A request received from a client.
+struct request
+{
+ /// The request method, e.g. "GET", "POST".
+ std::string method;
+
+ /// The requested URI, such as a path to a file.
+ std::string uri;
+
+ /// Major version number, usually 1.
+ int http_version_major;
+
+ /// Minor version number, usually 0 or 1.
+ int http_version_minor;
+
+ /// The headers included with the request.
+ std::vector<header> headers;
+
+ /// The optional content sent with the request.
+ std::string content;
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_REQUEST_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.cpp
new file mode 100644
index 00000000000..0ec31ad3939
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.cpp
@@ -0,0 +1,226 @@
+//
+// request_parser.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_parser.hpp"
+#include <algorithm>
+#include <cctype>
+#include <boost/lexical_cast.hpp>
+#include "request.hpp"
+
+namespace http {
+namespace server4 {
+
+// Enable the pseudo-keywords reenter, yield and fork.
+#include <asio/yield.hpp>
+
+std::string request_parser::content_length_name_ = "Content-Length";
+
+boost::tribool request_parser::consume(request& req, char c)
+{
+ reenter (this)
+ {
+ req.method.clear();
+ req.uri.clear();
+ req.http_version_major = 0;
+ req.http_version_minor = 0;
+ req.headers.clear();
+ req.content.clear();
+ content_length_ = 0;
+
+ // Request method.
+ while (is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != ' ')
+ {
+ req.method.push_back(c);
+ yield return boost::indeterminate;
+ }
+ if (req.method.empty())
+ return false;
+
+ // Space.
+ if (c != ' ') return false;
+ yield return boost::indeterminate;
+
+ // URI.
+ while (!is_ctl(c) && c != ' ')
+ {
+ req.uri.push_back(c);
+ yield return boost::indeterminate;
+ }
+ if (req.uri.empty()) return false;
+
+ // Space.
+ if (c != ' ') return false;
+ yield return boost::indeterminate;
+
+ // HTTP protocol identifier.
+ if (c != 'H') return false;
+ yield return boost::indeterminate;
+ if (c != 'T') return false;
+ yield return boost::indeterminate;
+ if (c != 'T') return false;
+ yield return boost::indeterminate;
+ if (c != 'P') return false;
+ yield return boost::indeterminate;
+
+ // Slash.
+ if (c != '/') return false;
+ yield return boost::indeterminate;
+
+ // Major version number.
+ if (!is_digit(c)) return false;
+ while (is_digit(c))
+ {
+ req.http_version_major = req.http_version_major * 10 + c - '0';
+ yield return boost::indeterminate;
+ }
+
+ // Dot.
+ if (c != '.') return false;
+ yield return boost::indeterminate;
+
+ // Minor version number.
+ if (!is_digit(c)) return false;
+ while (is_digit(c))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + c - '0';
+ yield return boost::indeterminate;
+ }
+
+ // CRLF.
+ if (c != '\r') return false;
+ yield return boost::indeterminate;
+ if (c != '\n') return false;
+ yield return boost::indeterminate;
+
+ // Headers.
+ while ((is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != '\r')
+ || (c == ' ' || c == '\t'))
+ {
+ if (c == ' ' || c == '\t')
+ {
+ // Leading whitespace. Must be continuation of previous header's value.
+ if (req.headers.empty()) return false;
+ while (c == ' ' || c == '\t')
+ yield return boost::indeterminate;
+ }
+ else
+ {
+ // Start the next header.
+ req.headers.push_back(header());
+
+ // Header name.
+ while (is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != ':')
+ {
+ req.headers.back().name.push_back(c);
+ yield return boost::indeterminate;
+ }
+
+ // Colon and space separates the header name from the header value.
+ if (c != ':') return false;
+ yield return boost::indeterminate;
+ if (c != ' ') return false;
+ yield return boost::indeterminate;
+ }
+
+ // Header value.
+ while (is_char(c) && !is_ctl(c) && c != '\r')
+ {
+ req.headers.back().value.push_back(c);
+ yield return boost::indeterminate;
+ }
+
+ // CRLF.
+ if (c != '\r') return false;
+ yield return boost::indeterminate;
+ if (c != '\n') return false;
+ yield return boost::indeterminate;
+ }
+
+ // CRLF.
+ if (c != '\r') return false;
+ yield return boost::indeterminate;
+ if (c != '\n') return false;
+
+ // Check for optional Content-Length header.
+ for (std::size_t i = 0; i < req.headers.size(); ++i)
+ {
+ if (headers_equal(req.headers[i].name, content_length_name_))
+ {
+ try
+ {
+ content_length_ =
+ boost::lexical_cast<std::size_t>(req.headers[i].value);
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ return false;
+ }
+ }
+ }
+
+ // Content.
+ while (req.content.size() < content_length_)
+ {
+ yield return boost::indeterminate;
+ req.content.push_back(c);
+ }
+ }
+
+ return true;
+}
+
+// Disable the pseudo-keywords reenter, yield and fork.
+#include <asio/unyield.hpp>
+
+bool request_parser::is_char(int c)
+{
+ return c >= 0 && c <= 127;
+}
+
+bool request_parser::is_ctl(int c)
+{
+ return (c >= 0 && c <= 31) || (c == 127);
+}
+
+bool request_parser::is_tspecial(int c)
+{
+ switch (c)
+ {
+ case '(': case ')': case '<': case '>': case '@':
+ case ',': case ';': case ':': case '\\': case '"':
+ case '/': case '[': case ']': case '?': case '=':
+ case '{': case '}': case ' ': case '\t':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_digit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+bool request_parser::tolower_compare(char a, char b)
+{
+ return std::tolower(a) == std::tolower(b);
+}
+
+bool request_parser::headers_equal(const std::string& a, const std::string& b)
+{
+ if (a.length() != b.length())
+ return false;
+
+ return std::equal(a.begin(), a.end(), b.begin(),
+ &request_parser::tolower_compare);
+}
+
+} // namespace server4
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.hpp
new file mode 100644
index 00000000000..a61356e36a6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/request_parser.hpp
@@ -0,0 +1,78 @@
+//
+// request_parser.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_REQUEST_PARSER_HPP
+#define HTTP_SERVER4_REQUEST_PARSER_HPP
+
+#include <string>
+#include <boost/logic/tribool.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <asio/coroutine.hpp>
+
+namespace http {
+namespace server4 {
+
+struct request;
+
+/// Parser for incoming requests.
+class request_parser : asio::coroutine
+{
+public:
+ /// Parse some data. The tribool return value is true when a complete request
+ /// has been parsed, false if the data is invalid, indeterminate when more
+ /// data is required. The InputIterator return value indicates how much of the
+ /// input has been consumed.
+ template <typename InputIterator>
+ boost::tuple<boost::tribool, InputIterator> parse(request& req,
+ InputIterator begin, InputIterator end)
+ {
+ while (begin != end)
+ {
+ boost::tribool result = consume(req, *begin++);
+ if (result || !result)
+ return boost::make_tuple(result, begin);
+ }
+ boost::tribool result = boost::indeterminate;
+ return boost::make_tuple(result, begin);
+ }
+
+private:
+ /// The name of the content length header.
+ static std::string content_length_name_;
+
+ /// Content length as decoded from headers. Defaults to 0.
+ std::size_t content_length_;
+
+ /// Handle the next character of input.
+ boost::tribool consume(request& req, char input);
+
+ /// Check if a byte is an HTTP character.
+ static bool is_char(int c);
+
+ /// Check if a byte is an HTTP control character.
+ static bool is_ctl(int c);
+
+ /// Check if a byte is defined as an HTTP tspecial character.
+ static bool is_tspecial(int c);
+
+ /// Check if a byte is a digit.
+ static bool is_digit(int c);
+
+ /// Check if two characters are equal, without regard to case.
+ static bool tolower_compare(char a, char b);
+
+ /// Check whether the two request header names match.
+ bool headers_equal(const std::string& a, const std::string& b);
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_REQUEST_PARSER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/server.cpp b/3rdparty/asio/src/examples/cpp03/http/server4/server.cpp
new file mode 100644
index 00000000000..04d81a984b6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/server.cpp
@@ -0,0 +1,122 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include "request.hpp"
+#include "reply.hpp"
+
+namespace http {
+namespace server4 {
+
+server::server(asio::io_context& io_context,
+ const std::string& address, const std::string& port,
+ boost::function<void(const request&, reply&)> request_handler)
+ : request_handler_(request_handler)
+{
+ tcp::resolver resolver(io_context);
+ asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ acceptor_.reset(new tcp::acceptor(io_context, endpoint));
+}
+
+// Enable the pseudo-keywords reenter, yield and fork.
+#include <asio/yield.hpp>
+
+void server::operator()(asio::error_code ec, std::size_t length)
+{
+ // In this example we keep the error handling code in one place by
+ // hoisting it outside the coroutine. An alternative approach would be to
+ // check the value of ec after each yield for an asynchronous operation.
+ if (!ec)
+ {
+ // On reentering a coroutine, control jumps to the location of the last
+ // yield or fork. The argument to the "reenter" pseudo-keyword can be a
+ // pointer or reference to an object of type coroutine.
+ reenter (this)
+ {
+ // Loop to accept incoming connections.
+ do
+ {
+ // Create a new socket for the next incoming connection.
+ socket_.reset(new tcp::socket(acceptor_->get_executor().context()));
+
+ // Accept a new connection. The "yield" pseudo-keyword saves the current
+ // line number and exits the coroutine's "reenter" block. We use the
+ // server coroutine as the completion handler for the async_accept
+ // operation. When the asynchronous operation completes, the io_context
+ // invokes the function call operator, we "reenter" the coroutine, and
+ // then control resumes at the following line.
+ yield acceptor_->async_accept(*socket_, *this);
+
+ // We "fork" by cloning a new server coroutine to handle the connection.
+ // After forking we have a parent coroutine and a child coroutine. Both
+ // parent and child continue execution at the following line. They can
+ // be distinguished using the functions coroutine::is_parent() and
+ // coroutine::is_child().
+ fork server(*this)();
+
+ // The parent continues looping to accept the next incoming connection.
+ // The child exits the loop and processes the connection.
+ } while (is_parent());
+
+ // Create the objects needed to receive a request on the connection.
+ buffer_.reset(new boost::array<char, 8192>);
+ request_.reset(new request);
+
+ // Loop until a complete request (or an invalid one) has been received.
+ do
+ {
+ // Receive some more data. When control resumes at the following line,
+ // the ec and length parameters reflect the result of the asynchronous
+ // operation.
+ yield socket_->async_read_some(asio::buffer(*buffer_), *this);
+
+ // Parse the data we just received.
+ boost::tie(valid_request_, boost::tuples::ignore)
+ = request_parser_.parse(*request_,
+ buffer_->data(), buffer_->data() + length);
+
+ // An indeterminate result means we need more data, so keep looping.
+ } while (boost::indeterminate(valid_request_));
+
+ // Create the reply object that will be sent back to the client.
+ reply_.reset(new reply);
+
+ if (valid_request_)
+ {
+ // A valid request was received. Call the user-supplied function object
+ // to process the request and compose a reply.
+ request_handler_(*request_, *reply_);
+ }
+ else
+ {
+ // The request was invalid.
+ *reply_ = reply::stock_reply(reply::bad_request);
+ }
+
+ // Send the reply back to the client.
+ yield asio::async_write(*socket_, reply_->to_buffers(), *this);
+
+ // Initiate graceful connection closure.
+ socket_->shutdown(tcp::socket::shutdown_both, ec);
+ }
+ }
+
+ // If an error occurs then the coroutine is not reentered. Consequently, no
+ // new asynchronous operations are started. This means that all shared_ptr
+ // references will disappear and the resources associated with the coroutine
+ // will be destroyed automatically after this function call returns.
+}
+
+// Disable the pseudo-keywords reenter, yield and fork.
+#include <asio/unyield.hpp>
+
+} // namespace server4
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp03/http/server4/server.hpp b/3rdparty/asio/src/examples/cpp03/http/server4/server.hpp
new file mode 100644
index 00000000000..580ece5e097
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/http/server4/server.hpp
@@ -0,0 +1,73 @@
+//
+// server.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER4_SERVER_HPP
+#define HTTP_SERVER4_SERVER_HPP
+
+#include <asio.hpp>
+#include <string>
+#include <boost/array.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include "request_parser.hpp"
+
+namespace http {
+namespace server4 {
+
+struct request;
+struct reply;
+
+/// The top-level coroutine of the HTTP server.
+class server : asio::coroutine
+{
+public:
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit server(asio::io_context& io_context,
+ const std::string& address, const std::string& port,
+ boost::function<void(const request&, reply&)> request_handler);
+
+ /// Perform work associated with the server.
+ void operator()(
+ asio::error_code ec = asio::error_code(),
+ std::size_t length = 0);
+
+private:
+ typedef asio::ip::tcp tcp;
+
+ /// The user-supplied handler for all incoming requests.
+ boost::function<void(const request&, reply&)> request_handler_;
+
+ /// Acceptor used to listen for incoming connections.
+ boost::shared_ptr<tcp::acceptor> acceptor_;
+
+ /// The current connection from a client.
+ boost::shared_ptr<tcp::socket> socket_;
+
+ /// Buffer for incoming data.
+ boost::shared_ptr<boost::array<char, 8192> > buffer_;
+
+ /// The incoming request.
+ boost::shared_ptr<request> request_;
+
+ /// Whether the request is valid or not.
+ boost::tribool valid_request_;
+
+ /// The parser for the incoming request.
+ request_parser request_parser_;
+
+ /// The reply to be sent back to the client.
+ boost::shared_ptr<reply> reply_;
+};
+
+} // namespace server4
+} // namespace http
+
+#endif // HTTP_SERVER4_SERVER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/icmp/.gitignore b/3rdparty/asio/src/examples/cpp03/icmp/.gitignore
new file mode 100644
index 00000000000..62ea912e2e4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/icmp/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+ping
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp b/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp
new file mode 100644
index 00000000000..3b7b4bf5032
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp
@@ -0,0 +1,94 @@
+//
+// icmp_header.hpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ICMP_HEADER_HPP
+#define ICMP_HEADER_HPP
+
+#include <istream>
+#include <ostream>
+#include <algorithm>
+
+// ICMP header for both IPv4 and IPv6.
+//
+// The wire format of an ICMP header is:
+//
+// 0 8 16 31
+// +---------------+---------------+------------------------------+ ---
+// | | | | ^
+// | type | code | checksum | |
+// | | | | |
+// +---------------+---------------+------------------------------+ 8 bytes
+// | | | |
+// | identifier | sequence number | |
+// | | | v
+// +-------------------------------+------------------------------+ ---
+
+class icmp_header
+{
+public:
+ enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,
+ redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,
+ timestamp_request = 13, timestamp_reply = 14, info_request = 15,
+ info_reply = 16, address_request = 17, address_reply = 18 };
+
+ icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
+
+ unsigned char type() const { return rep_[0]; }
+ unsigned char code() const { return rep_[1]; }
+ unsigned short checksum() const { return decode(2, 3); }
+ unsigned short identifier() const { return decode(4, 5); }
+ unsigned short sequence_number() const { return decode(6, 7); }
+
+ void type(unsigned char n) { rep_[0] = n; }
+ void code(unsigned char n) { rep_[1] = n; }
+ void checksum(unsigned short n) { encode(2, 3, n); }
+ void identifier(unsigned short n) { encode(4, 5, n); }
+ void sequence_number(unsigned short n) { encode(6, 7, n); }
+
+ friend std::istream& operator>>(std::istream& is, icmp_header& header)
+ { return is.read(reinterpret_cast<char*>(header.rep_), 8); }
+
+ friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)
+ { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }
+
+private:
+ unsigned short decode(int a, int b) const
+ { return (rep_[a] << 8) + rep_[b]; }
+
+ void encode(int a, int b, unsigned short n)
+ {
+ rep_[a] = static_cast<unsigned char>(n >> 8);
+ rep_[b] = static_cast<unsigned char>(n & 0xFF);
+ }
+
+ unsigned char rep_[8];
+};
+
+template <typename Iterator>
+void compute_checksum(icmp_header& header,
+ Iterator body_begin, Iterator body_end)
+{
+ unsigned int sum = (header.type() << 8) + header.code()
+ + header.identifier() + header.sequence_number();
+
+ Iterator body_iter = body_begin;
+ while (body_iter != body_end)
+ {
+ sum += (static_cast<unsigned char>(*body_iter++) << 8);
+ if (body_iter != body_end)
+ sum += static_cast<unsigned char>(*body_iter++);
+ }
+
+ sum = (sum >> 16) + (sum & 0xFFFF);
+ sum += (sum >> 16);
+ header.checksum(static_cast<unsigned short>(~sum));
+}
+
+#endif // ICMP_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/icmp/ipv4_header.hpp b/3rdparty/asio/src/examples/cpp03/icmp/ipv4_header.hpp
new file mode 100644
index 00000000000..6785fd74d6c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/icmp/ipv4_header.hpp
@@ -0,0 +1,102 @@
+//
+// ipv4_header.hpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 IPV4_HEADER_HPP
+#define IPV4_HEADER_HPP
+
+#include <algorithm>
+#include <asio/ip/address_v4.hpp>
+
+// Packet header for IPv4.
+//
+// The wire format of an IPv4 header is:
+//
+// 0 8 16 31
+// +-------+-------+---------------+------------------------------+ ---
+// | | | | | ^
+// |version|header | type of | total length in bytes | |
+// | (4) | length| service | | |
+// +-------+-------+---------------+-+-+-+------------------------+ |
+// | | | | | | |
+// | identification |0|D|M| fragment offset | |
+// | | |F|F| | |
+// +---------------+---------------+-+-+-+------------------------+ |
+// | | | | |
+// | time to live | protocol | header checksum | 20 bytes
+// | | | | |
+// +---------------+---------------+------------------------------+ |
+// | | |
+// | source IPv4 address | |
+// | | |
+// +--------------------------------------------------------------+ |
+// | | |
+// | destination IPv4 address | |
+// | | v
+// +--------------------------------------------------------------+ ---
+// | | ^
+// | | |
+// / options (if any) / 0 - 40
+// / / bytes
+// | | |
+// | | v
+// +--------------------------------------------------------------+ ---
+
+class ipv4_header
+{
+public:
+ ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
+
+ unsigned char version() const { return (rep_[0] >> 4) & 0xF; }
+ unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }
+ unsigned char type_of_service() const { return rep_[1]; }
+ unsigned short total_length() const { return decode(2, 3); }
+ unsigned short identification() const { return decode(4, 5); }
+ bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }
+ bool more_fragments() const { return (rep_[6] & 0x20) != 0; }
+ unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }
+ unsigned int time_to_live() const { return rep_[8]; }
+ unsigned char protocol() const { return rep_[9]; }
+ unsigned short header_checksum() const { return decode(10, 11); }
+
+ asio::ip::address_v4 source_address() const
+ {
+ asio::ip::address_v4::bytes_type bytes
+ = { { rep_[12], rep_[13], rep_[14], rep_[15] } };
+ return asio::ip::address_v4(bytes);
+ }
+
+ asio::ip::address_v4 destination_address() const
+ {
+ asio::ip::address_v4::bytes_type bytes
+ = { { rep_[16], rep_[17], rep_[18], rep_[19] } };
+ return asio::ip::address_v4(bytes);
+ }
+
+ friend std::istream& operator>>(std::istream& is, ipv4_header& header)
+ {
+ is.read(reinterpret_cast<char*>(header.rep_), 20);
+ if (header.version() != 4)
+ is.setstate(std::ios::failbit);
+ std::streamsize options_length = header.header_length() - 20;
+ if (options_length < 0 || options_length > 40)
+ is.setstate(std::ios::failbit);
+ else
+ is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);
+ return is;
+ }
+
+private:
+ unsigned short decode(int a, int b) const
+ { return (rep_[a] << 8) + rep_[b]; }
+
+ unsigned char rep_[60];
+};
+
+#endif // IPV4_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/icmp/ping.cpp b/3rdparty/asio/src/examples/cpp03/icmp/ping.cpp
new file mode 100644
index 00000000000..3a1d278415d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/icmp/ping.cpp
@@ -0,0 +1,161 @@
+//
+// ping.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <istream>
+#include <iostream>
+#include <ostream>
+
+#include "icmp_header.hpp"
+#include "ipv4_header.hpp"
+
+using asio::ip::icmp;
+using asio::deadline_timer;
+namespace posix_time = boost::posix_time;
+
+class pinger
+{
+public:
+ pinger(asio::io_context& io_context, const char* destination)
+ : resolver_(io_context), socket_(io_context, icmp::v4()),
+ timer_(io_context), sequence_number_(0), num_replies_(0)
+ {
+ destination_ = *resolver_.resolve(icmp::v4(), destination, "").begin();
+
+ start_send();
+ start_receive();
+ }
+
+private:
+ void start_send()
+ {
+ std::string body("\"Hello!\" from Asio ping.");
+
+ // Create an ICMP header for an echo request.
+ icmp_header echo_request;
+ echo_request.type(icmp_header::echo_request);
+ echo_request.code(0);
+ echo_request.identifier(get_identifier());
+ echo_request.sequence_number(++sequence_number_);
+ compute_checksum(echo_request, body.begin(), body.end());
+
+ // Encode the request packet.
+ asio::streambuf request_buffer;
+ std::ostream os(&request_buffer);
+ os << echo_request << body;
+
+ // Send the request.
+ time_sent_ = posix_time::microsec_clock::universal_time();
+ socket_.send_to(request_buffer.data(), destination_);
+
+ // Wait up to five seconds for a reply.
+ num_replies_ = 0;
+ timer_.expires_at(time_sent_ + posix_time::seconds(5));
+ timer_.async_wait(boost::bind(&pinger::handle_timeout, this));
+ }
+
+ void handle_timeout()
+ {
+ if (num_replies_ == 0)
+ std::cout << "Request timed out" << std::endl;
+
+ // Requests must be sent no less than one second apart.
+ timer_.expires_at(time_sent_ + posix_time::seconds(1));
+ timer_.async_wait(boost::bind(&pinger::start_send, this));
+ }
+
+ void start_receive()
+ {
+ // Discard any data already in the buffer.
+ reply_buffer_.consume(reply_buffer_.size());
+
+ // Wait for a reply. We prepare the buffer to receive up to 64KB.
+ socket_.async_receive(reply_buffer_.prepare(65536),
+ boost::bind(&pinger::handle_receive, this, _2));
+ }
+
+ void handle_receive(std::size_t length)
+ {
+ // The actual number of bytes received is committed to the buffer so that we
+ // can extract it using a std::istream object.
+ reply_buffer_.commit(length);
+
+ // Decode the reply packet.
+ std::istream is(&reply_buffer_);
+ ipv4_header ipv4_hdr;
+ icmp_header icmp_hdr;
+ is >> ipv4_hdr >> icmp_hdr;
+
+ // We can receive all ICMP packets received by the host, so we need to
+ // filter out only the echo replies that match the our identifier and
+ // expected sequence number.
+ if (is && icmp_hdr.type() == icmp_header::echo_reply
+ && icmp_hdr.identifier() == get_identifier()
+ && icmp_hdr.sequence_number() == sequence_number_)
+ {
+ // If this is the first reply, interrupt the five second timeout.
+ if (num_replies_++ == 0)
+ timer_.cancel();
+
+ // Print out some information about the reply packet.
+ posix_time::ptime now = posix_time::microsec_clock::universal_time();
+ std::cout << length - ipv4_hdr.header_length()
+ << " bytes from " << ipv4_hdr.source_address()
+ << ": icmp_seq=" << icmp_hdr.sequence_number()
+ << ", ttl=" << ipv4_hdr.time_to_live()
+ << ", time=" << (now - time_sent_).total_milliseconds() << " ms"
+ << std::endl;
+ }
+
+ start_receive();
+ }
+
+ static unsigned short get_identifier()
+ {
+#if defined(ASIO_WINDOWS)
+ return static_cast<unsigned short>(::GetCurrentProcessId());
+#else
+ return static_cast<unsigned short>(::getpid());
+#endif
+ }
+
+ icmp::resolver resolver_;
+ icmp::endpoint destination_;
+ icmp::socket socket_;
+ deadline_timer timer_;
+ unsigned short sequence_number_;
+ posix_time::ptime time_sent_;
+ asio::streambuf reply_buffer_;
+ std::size_t num_replies_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: ping <host>" << std::endl;
+#if !defined(ASIO_WINDOWS)
+ std::cerr << "(You may need to run this program as root.)" << std::endl;
+#endif
+ return 1;
+ }
+
+ asio::io_context io_context;
+ pinger p(io_context, argv[1]);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+}
diff --git a/3rdparty/asio/src/examples/cpp03/invocation/.gitignore b/3rdparty/asio/src/examples/cpp03/invocation/.gitignore
new file mode 100644
index 00000000000..e5876b7811a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/invocation/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+prioritised_handlers
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp b/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp
new file mode 100644
index 00000000000..73897946966
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp
@@ -0,0 +1,162 @@
+//
+// prioritised_handlers.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio.hpp"
+#include <boost/function.hpp>
+#include <iostream>
+#include <queue>
+
+using asio::ip::tcp;
+
+class handler_priority_queue
+{
+public:
+ void add(int priority, boost::function<void()> function)
+ {
+ handlers_.push(queued_handler(priority, function));
+ }
+
+ void execute_all()
+ {
+ while (!handlers_.empty())
+ {
+ queued_handler handler = handlers_.top();
+ handler.execute();
+ handlers_.pop();
+ }
+ }
+
+ // A generic wrapper class for handlers to allow the invocation to be hooked.
+ template <typename Handler>
+ class wrapped_handler
+ {
+ public:
+ wrapped_handler(handler_priority_queue& q, int p, Handler h)
+ : queue_(q), priority_(p), handler_(h)
+ {
+ }
+
+ void operator()()
+ {
+ handler_();
+ }
+
+ template <typename Arg1>
+ void operator()(Arg1 arg1)
+ {
+ handler_(arg1);
+ }
+
+ template <typename Arg1, typename Arg2>
+ void operator()(Arg1 arg1, Arg2 arg2)
+ {
+ handler_(arg1, arg2);
+ }
+
+ //private:
+ handler_priority_queue& queue_;
+ int priority_;
+ Handler handler_;
+ };
+
+ template <typename Handler>
+ wrapped_handler<Handler> wrap(int priority, Handler handler)
+ {
+ return wrapped_handler<Handler>(*this, priority, handler);
+ }
+
+private:
+ class queued_handler
+ {
+ public:
+ queued_handler(int p, boost::function<void()> f)
+ : priority_(p), function_(f)
+ {
+ }
+
+ void execute()
+ {
+ function_();
+ }
+
+ friend bool operator<(const queued_handler& a,
+ const queued_handler& b)
+ {
+ return a.priority_ < b.priority_;
+ }
+
+ private:
+ int priority_;
+ boost::function<void()> function_;
+ };
+
+ std::priority_queue<queued_handler> handlers_;
+};
+
+// Custom invocation hook for wrapped handlers.
+template <typename Function, typename Handler>
+void asio_handler_invoke(Function f,
+ handler_priority_queue::wrapped_handler<Handler>* h)
+{
+ h->queue_.add(h->priority_, f);
+}
+
+//----------------------------------------------------------------------
+
+void high_priority_handler(const asio::error_code& /*ec*/)
+{
+ std::cout << "High priority handler\n";
+}
+
+void middle_priority_handler(const asio::error_code& /*ec*/)
+{
+ std::cout << "Middle priority handler\n";
+}
+
+void low_priority_handler()
+{
+ std::cout << "Low priority handler\n";
+}
+
+int main()
+{
+ asio::io_context io_context;
+
+ handler_priority_queue pri_queue;
+
+ // Post a completion handler to be run immediately.
+ asio::post(io_context, pri_queue.wrap(0, low_priority_handler));
+
+ // Start an asynchronous accept that will complete immediately.
+ tcp::endpoint endpoint(asio::ip::address_v4::loopback(), 0);
+ tcp::acceptor acceptor(io_context, endpoint);
+ tcp::socket server_socket(io_context);
+ acceptor.async_accept(server_socket,
+ pri_queue.wrap(100, high_priority_handler));
+ tcp::socket client_socket(io_context);
+ client_socket.connect(acceptor.local_endpoint());
+
+ // Set a deadline timer to expire immediately.
+ asio::deadline_timer timer(io_context);
+ timer.expires_at(boost::posix_time::neg_infin);
+ timer.async_wait(pri_queue.wrap(42, middle_priority_handler));
+
+ while (io_context.run_one())
+ {
+ // The custom invocation hook adds the handlers to the priority queue
+ // rather than executing them from within the poll_one() call.
+ while (io_context.poll_one())
+ ;
+
+ pri_queue.execute_all();
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/iostreams/.gitignore b/3rdparty/asio/src/examples/cpp03/iostreams/.gitignore
new file mode 100644
index 00000000000..bc2b4f8f7fe
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/iostreams/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+*_server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/iostreams/daytime_client.cpp b/3rdparty/asio/src/examples/cpp03/iostreams/daytime_client.cpp
new file mode 100644
index 00000000000..4d0f68ca989
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/iostreams/daytime_client.cpp
@@ -0,0 +1,44 @@
+//
+// daytime_client.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: daytime_client <host>" << std::endl;
+ return 1;
+ }
+
+ tcp::iostream s(argv[1], "daytime");
+ if (!s)
+ {
+ std::cout << "Unable to connect: " << s.error().message() << std::endl;
+ return 1;
+ }
+
+ std::string line;
+ std::getline(s, line);
+ std::cout << line << std::endl;
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/iostreams/daytime_server.cpp b/3rdparty/asio/src/examples/cpp03/iostreams/daytime_server.cpp
new file mode 100644
index 00000000000..ed3f94b0505
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/iostreams/daytime_server.cpp
@@ -0,0 +1,51 @@
+//
+// daytime_server.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ tcp::endpoint endpoint(tcp::v4(), 13);
+ tcp::acceptor acceptor(io_context, endpoint);
+
+ for (;;)
+ {
+ tcp::iostream stream;
+ asio::error_code ec;
+ acceptor.accept(stream.socket(), ec);
+ if (!ec)
+ {
+ stream << make_daytime_string();
+ }
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/iostreams/http_client.cpp b/3rdparty/asio/src/examples/cpp03/iostreams/http_client.cpp
new file mode 100644
index 00000000000..247df0f37e4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/iostreams/http_client.cpp
@@ -0,0 +1,91 @@
+//
+// http_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <asio/ip/tcp.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cout << "Usage: http_client <server> <path>\n";
+ std::cout << "Example:\n";
+ std::cout << " http_client www.boost.org /LICENSE_1_0.txt\n";
+ return 1;
+ }
+
+ asio::ip::tcp::iostream s;
+
+ // The entire sequence of I/O operations must complete within 60 seconds.
+ // If an expiry occurs, the socket is automatically closed and the stream
+ // becomes bad.
+ s.expires_after(boost::posix_time::seconds(60));
+
+ // Establish a connection to the server.
+ s.connect(argv[1], "http");
+ if (!s)
+ {
+ std::cout << "Unable to connect: " << s.error().message() << "\n";
+ return 1;
+ }
+
+ // Send the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ s << "GET " << argv[2] << " HTTP/1.0\r\n";
+ s << "Host: " << argv[1] << "\r\n";
+ s << "Accept: */*\r\n";
+ s << "Connection: close\r\n\r\n";
+
+ // By default, the stream is tied with itself. This means that the stream
+ // automatically flush the buffered output before attempting a read. It is
+ // not necessary not explicitly flush the stream at this point.
+
+ // Check that response is OK.
+ std::string http_version;
+ s >> http_version;
+ unsigned int status_code;
+ s >> status_code;
+ std::string status_message;
+ std::getline(s, status_message);
+ if (!s || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ return 1;
+ }
+ if (status_code != 200)
+ {
+ std::cout << "Response returned with status code " << status_code << "\n";
+ return 1;
+ }
+
+ // Process the response headers, which are terminated by a blank line.
+ std::string header;
+ while (std::getline(s, header) && header != "\r")
+ std::cout << header << "\n";
+ std::cout << "\n";
+
+ // Write the remaining data to output.
+ std::cout << s.rdbuf();
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/local/.gitignore b/3rdparty/asio/src/examples/cpp03/local/.gitignore
new file mode 100644
index 00000000000..688277b48d0
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/local/.gitignore
@@ -0,0 +1,13 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+connect_pair
+stream_server
+stream_client
+iostream_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/local/connect_pair.cpp b/3rdparty/asio/src/examples/cpp03/local/connect_pair.cpp
new file mode 100644
index 00000000000..92e0ae866d5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/local/connect_pair.cpp
@@ -0,0 +1,141 @@
+//
+// connect_pair.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <cctype>
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+
+using asio::local::stream_protocol;
+
+class uppercase_filter
+{
+public:
+ uppercase_filter(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ stream_protocol::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ // Wait for request.
+ socket_.async_read_some(asio::buffer(data_),
+ boost::bind(&uppercase_filter::handle_read,
+ this, asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+private:
+ void handle_read(const asio::error_code& ec, std::size_t size)
+ {
+ if (!ec)
+ {
+ // Compute result.
+ for (std::size_t i = 0; i < size; ++i)
+ data_[i] = std::toupper(data_[i]);
+
+ // Send result.
+ asio::async_write(socket_, asio::buffer(data_, size),
+ boost::bind(&uppercase_filter::handle_write,
+ this, asio::placeholders::error));
+ }
+ else
+ {
+ throw asio::system_error(ec);
+ }
+ }
+
+ void handle_write(const asio::error_code& ec)
+ {
+ if (!ec)
+ {
+ // Wait for request.
+ socket_.async_read_some(asio::buffer(data_),
+ boost::bind(&uppercase_filter::handle_read,
+ this, asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ throw asio::system_error(ec);
+ }
+ }
+
+ stream_protocol::socket socket_;
+ boost::array<char, 512> data_;
+};
+
+void run(asio::io_context* io_context)
+{
+ try
+ {
+ io_context->run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception in thread: " << e.what() << "\n";
+ std::exit(1);
+ }
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ // Create filter and establish a connection to it.
+ uppercase_filter filter(io_context);
+ stream_protocol::socket socket(io_context);
+ asio::local::connect_pair(socket, filter.socket());
+ filter.start();
+
+ // The io_context runs in a background thread to perform filtering.
+ asio::thread thread(boost::bind(run, &io_context));
+
+ for (;;)
+ {
+ // Collect request from user.
+ std::cout << "Enter a string: ";
+ std::string request;
+ std::getline(std::cin, request);
+
+ // Send request to filter.
+ asio::write(socket, asio::buffer(request));
+
+ // Wait for reply from filter.
+ std::vector<char> reply(request.size());
+ asio::read(socket, asio::buffer(reply));
+
+ // Show reply to user.
+ std::cout << "Result: ";
+ std::cout.write(&reply[0], request.size());
+ std::cout << std::endl;
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ std::exit(1);
+ }
+}
+
+#else // defined(ASIO_HAS_LOCAL_SOCKETS)
+# error Local sockets not available on this platform.
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
diff --git a/3rdparty/asio/src/examples/cpp03/local/iostream_client.cpp b/3rdparty/asio/src/examples/cpp03/local/iostream_client.cpp
new file mode 100644
index 00000000000..d28d29e88c1
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/local/iostream_client.cpp
@@ -0,0 +1,62 @@
+//
+// stream_client.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+
+using asio::local::stream_protocol;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: iostream_client <file>\n";
+ return 1;
+ }
+
+ stream_protocol::endpoint ep(argv[1]);
+ stream_protocol::iostream s(ep);
+ if (!s)
+ {
+ std::cerr << "Unable to connect: " << s.error().message() << std::endl;
+ return 1;
+ }
+
+ using namespace std; // For strlen.
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t length = strlen(request);
+ s << request;
+
+ char reply[max_length];
+ s.read(reply, length);
+ std::cout << "Reply is: ";
+ std::cout.write(reply, length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
+
+#else // defined(ASIO_HAS_LOCAL_SOCKETS)
+# error Local sockets not available on this platform.
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
diff --git a/3rdparty/asio/src/examples/cpp03/local/stream_client.cpp b/3rdparty/asio/src/examples/cpp03/local/stream_client.cpp
new file mode 100644
index 00000000000..6374f8fb534
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/local/stream_client.cpp
@@ -0,0 +1,61 @@
+//
+// stream_client.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+
+using asio::local::stream_protocol;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: stream_client <file>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ stream_protocol::socket s(io_context);
+ s.connect(stream_protocol::endpoint(argv[1]));
+
+ using namespace std; // For strlen.
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = strlen(request);
+ asio::write(s, asio::buffer(request, request_length));
+
+ char reply[max_length];
+ size_t reply_length = asio::read(s,
+ asio::buffer(reply, request_length));
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
+
+#else // defined(ASIO_HAS_LOCAL_SOCKETS)
+# error Local sockets not available on this platform.
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
diff --git a/3rdparty/asio/src/examples/cpp03/local/stream_server.cpp b/3rdparty/asio/src/examples/cpp03/local/stream_server.cpp
new file mode 100644
index 00000000000..0bfe2788cae
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/local/stream_server.cpp
@@ -0,0 +1,141 @@
+//
+// stream_server.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdio>
+#include <iostream>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include "asio.hpp"
+
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+
+using asio::local::stream_protocol;
+
+class session
+ : public boost::enable_shared_from_this<session>
+{
+public:
+ session(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ stream_protocol::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ socket_.async_read_some(asio::buffer(data_),
+ boost::bind(&session::handle_read,
+ shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+ void handle_read(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ asio::async_write(socket_,
+ asio::buffer(data_, bytes_transferred),
+ boost::bind(&session::handle_write,
+ shared_from_this(),
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(asio::buffer(data_),
+ boost::bind(&session::handle_read,
+ shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+private:
+ // The socket used to communicate with the client.
+ stream_protocol::socket socket_;
+
+ // Buffer used to store data received from the client.
+ boost::array<char, 1024> data_;
+};
+
+typedef boost::shared_ptr<session> session_ptr;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, const std::string& file)
+ : io_context_(io_context),
+ acceptor_(io_context, stream_protocol::endpoint(file))
+ {
+ session_ptr new_session(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session_ptr new_session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+
+ new_session.reset(new session(io_context_));
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+private:
+ asio::io_context& io_context_;
+ stream_protocol::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: stream_server <file>\n";
+ std::cerr << "*** WARNING: existing file is removed ***\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ std::remove(argv[1]);
+ server s(io_context, argv[1]);
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
+
+#else // defined(ASIO_HAS_LOCAL_SOCKETS)
+# error Local sockets not available on this platform.
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
diff --git a/3rdparty/asio/src/examples/cpp03/multicast/.gitignore b/3rdparty/asio/src/examples/cpp03/multicast/.gitignore
new file mode 100644
index 00000000000..0c30ebdd7df
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/multicast/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+receiver
+sender
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/multicast/receiver.cpp b/3rdparty/asio/src/examples/cpp03/multicast/receiver.cpp
new file mode 100644
index 00000000000..5937050b0a8
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/multicast/receiver.cpp
@@ -0,0 +1,93 @@
+//
+// receiver.cpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include "asio.hpp"
+#include "boost/bind.hpp"
+
+const short multicast_port = 30001;
+
+class receiver
+{
+public:
+ receiver(asio::io_context& io_context,
+ const asio::ip::address& listen_address,
+ const asio::ip::address& multicast_address)
+ : socket_(io_context)
+ {
+ // Create the socket so that multiple may be bound to the same address.
+ asio::ip::udp::endpoint listen_endpoint(
+ listen_address, multicast_port);
+ socket_.open(listen_endpoint.protocol());
+ socket_.set_option(asio::ip::udp::socket::reuse_address(true));
+ socket_.bind(listen_endpoint);
+
+ // Join the multicast group.
+ socket_.set_option(
+ asio::ip::multicast::join_group(multicast_address));
+
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ boost::bind(&receiver::handle_receive_from, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+ void handle_receive_from(const asio::error_code& error,
+ size_t bytes_recvd)
+ {
+ if (!error)
+ {
+ std::cout.write(data_, bytes_recvd);
+ std::cout << std::endl;
+
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ boost::bind(&receiver::handle_receive_from, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+private:
+ asio::ip::udp::socket socket_;
+ asio::ip::udp::endpoint sender_endpoint_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: receiver <listen_address> <multicast_address>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 239.255.0.1\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 ff31::8000:1234\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+ receiver r(io_context,
+ asio::ip::make_address(argv[1]),
+ asio::ip::make_address(argv[2]));
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/multicast/sender.cpp b/3rdparty/asio/src/examples/cpp03/multicast/sender.cpp
new file mode 100644
index 00000000000..995f05aa48e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/multicast/sender.cpp
@@ -0,0 +1,99 @@
+//
+// sender.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "asio.hpp"
+#include "boost/bind.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+
+const short multicast_port = 30001;
+const int max_message_count = 10;
+
+class sender
+{
+public:
+ sender(asio::io_context& io_context,
+ const asio::ip::address& multicast_address)
+ : endpoint_(multicast_address, multicast_port),
+ socket_(io_context, endpoint_.protocol()),
+ timer_(io_context),
+ message_count_(0)
+ {
+ std::ostringstream os;
+ os << "Message " << message_count_++;
+ message_ = os.str();
+
+ socket_.async_send_to(
+ asio::buffer(message_), endpoint_,
+ boost::bind(&sender::handle_send_to, this,
+ asio::placeholders::error));
+ }
+
+ void handle_send_to(const asio::error_code& error)
+ {
+ if (!error && message_count_ < max_message_count)
+ {
+ timer_.expires_from_now(boost::posix_time::seconds(1));
+ timer_.async_wait(
+ boost::bind(&sender::handle_timeout, this,
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_timeout(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ std::ostringstream os;
+ os << "Message " << message_count_++;
+ message_ = os.str();
+
+ socket_.async_send_to(
+ asio::buffer(message_), endpoint_,
+ boost::bind(&sender::handle_send_to, this,
+ asio::placeholders::error));
+ }
+ }
+
+private:
+ asio::ip::udp::endpoint endpoint_;
+ asio::ip::udp::socket socket_;
+ asio::deadline_timer timer_;
+ int message_count_;
+ std::string message_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: sender <multicast_address>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " sender 239.255.0.1\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " sender ff31::8000:1234\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+ sender s(io_context, asio::ip::make_address(argv[1]));
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/nonblocking/.gitignore b/3rdparty/asio/src/examples/cpp03/nonblocking/.gitignore
new file mode 100644
index 00000000000..760e0dcebb4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/nonblocking/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+third_party_lib
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp b/3rdparty/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp
new file mode 100644
index 00000000000..8ec06f6034d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp
@@ -0,0 +1,240 @@
+//
+// third_party_lib.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <iostream>
+
+using asio::ip::tcp;
+
+namespace third_party_lib {
+
+// Simulation of a third party library that wants to perform read and write
+// operations directly on a socket. It needs to be polled to determine whether
+// it requires a read or write operation, and notified when the socket is ready
+// for reading or writing.
+class session
+{
+public:
+ session(tcp::socket& socket)
+ : socket_(socket),
+ state_(reading)
+ {
+ }
+
+ // Returns true if the third party library wants to be notified when the
+ // socket is ready for reading.
+ bool want_read() const
+ {
+ return state_ == reading;
+ }
+
+ // Notify that third party library that it should perform its read operation.
+ void do_read(asio::error_code& ec)
+ {
+ if (std::size_t len = socket_.read_some(asio::buffer(data_), ec))
+ {
+ write_buffer_ = asio::buffer(data_, len);
+ state_ = writing;
+ }
+ }
+
+ // Returns true if the third party library wants to be notified when the
+ // socket is ready for writing.
+ bool want_write() const
+ {
+ return state_ == writing;
+ }
+
+ // Notify that third party library that it should perform its write operation.
+ void do_write(asio::error_code& ec)
+ {
+ if (std::size_t len = socket_.write_some(
+ asio::buffer(write_buffer_), ec))
+ {
+ write_buffer_ = write_buffer_ + len;
+ state_ = asio::buffer_size(write_buffer_) > 0 ? writing : reading;
+ }
+ }
+
+private:
+ tcp::socket& socket_;
+ enum { reading, writing } state_;
+ boost::array<char, 128> data_;
+ asio::const_buffer write_buffer_;
+};
+
+} // namespace third_party_lib
+
+// The glue between asio's sockets and the third party library.
+class connection
+ : public boost::enable_shared_from_this<connection>
+{
+public:
+ typedef boost::shared_ptr<connection> pointer;
+
+ static pointer create(asio::io_context& io_context)
+ {
+ return pointer(new connection(io_context));
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ // Put the socket into non-blocking mode.
+ socket_.non_blocking(true);
+
+ start_operations();
+ }
+
+private:
+ connection(asio::io_context& io_context)
+ : socket_(io_context),
+ session_impl_(socket_),
+ read_in_progress_(false),
+ write_in_progress_(false)
+ {
+ }
+
+ void start_operations()
+ {
+ // Start a read operation if the third party library wants one.
+ if (session_impl_.want_read() && !read_in_progress_)
+ {
+ read_in_progress_ = true;
+ socket_.async_wait(tcp::socket::wait_read,
+ boost::bind(&connection::handle_read,
+ shared_from_this(),
+ asio::placeholders::error));
+ }
+
+ // Start a write operation if the third party library wants one.
+ if (session_impl_.want_write() && !write_in_progress_)
+ {
+ write_in_progress_ = true;
+ socket_.async_wait(tcp::socket::wait_write,
+ boost::bind(&connection::handle_write,
+ shared_from_this(),
+ asio::placeholders::error));
+ }
+ }
+
+ void handle_read(asio::error_code ec)
+ {
+ read_in_progress_ = false;
+
+ // Notify third party library that it can perform a read.
+ if (!ec)
+ session_impl_.do_read(ec);
+
+ // The third party library successfully performed a read on the socket.
+ // Start new read or write operations based on what it now wants.
+ if (!ec || ec == asio::error::would_block)
+ start_operations();
+
+ // Otherwise, an error occurred. Closing the socket cancels any outstanding
+ // asynchronous read or write operations. The connection object will be
+ // destroyed automatically once those outstanding operations complete.
+ else
+ socket_.close();
+ }
+
+ void handle_write(asio::error_code ec)
+ {
+ write_in_progress_ = false;
+
+ // Notify third party library that it can perform a write.
+ if (!ec)
+ session_impl_.do_write(ec);
+
+ // The third party library successfully performed a write on the socket.
+ // Start new read or write operations based on what it now wants.
+ if (!ec || ec == asio::error::would_block)
+ start_operations();
+
+ // Otherwise, an error occurred. Closing the socket cancels any outstanding
+ // asynchronous read or write operations. The connection object will be
+ // destroyed automatically once those outstanding operations complete.
+ else
+ socket_.close();
+ }
+
+private:
+ tcp::socket socket_;
+ third_party_lib::session session_impl_;
+ bool read_in_progress_;
+ bool write_in_progress_;
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, unsigned short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ connection::pointer new_connection =
+ connection::create(acceptor_.get_executor().context());
+
+ acceptor_.async_accept(new_connection->socket(),
+ boost::bind(&server::handle_accept, this, new_connection,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(connection::pointer new_connection,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_connection->start();
+ }
+
+ start_accept();
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: third_party_lib <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore b/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore
new file mode 100644
index 00000000000..692ea7e7e65
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+client
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp b/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp
new file mode 100644
index 00000000000..15d8e4803c1
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp
@@ -0,0 +1,192 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/if.hpp>
+#include <boost/shared_ptr.hpp>
+#include <algorithm>
+#include <cstdlib>
+#include <exception>
+#include <iostream>
+#include <string>
+#include "protocol.hpp"
+
+using namespace boost;
+using asio::ip::tcp;
+using asio::ip::udp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: client <host> <port>\n";
+ return 1;
+ }
+ using namespace std; // For atoi.
+ std::string host_name = argv[1];
+ std::string port = argv[2];
+
+ asio::io_context io_context;
+
+ // Determine the location of the server.
+ tcp::resolver resolver(io_context);
+ tcp::endpoint remote_endpoint = *resolver.resolve(host_name, port).begin();
+
+ // Establish the control connection to the server.
+ tcp::socket control_socket(io_context);
+ control_socket.connect(remote_endpoint);
+
+ // Create a datagram socket to receive data from the server.
+ boost::shared_ptr<udp::socket> data_socket(
+ new udp::socket(io_context, udp::endpoint(udp::v4(), 0)));
+
+ // Determine what port we will receive data on.
+ udp::endpoint data_endpoint = data_socket->local_endpoint();
+
+ // Ask the server to start sending us data.
+ control_request start = control_request::start(data_endpoint.port());
+ asio::write(control_socket, start.to_buffers());
+
+ unsigned long last_frame_number = 0;
+ for (;;)
+ {
+ // Receive 50 messages on the current data socket.
+ for (int i = 0; i < 50; ++i)
+ {
+ // Receive a frame from the server.
+ frame f;
+ data_socket->receive(f.to_buffers(), 0);
+ if (f.number() > last_frame_number)
+ {
+ last_frame_number = f.number();
+ std::cout << "\n" << f.payload();
+ }
+ }
+
+ // Time to switch to a new socket. To ensure seamless handover we will
+ // continue to receive packets using the old socket until data arrives on
+ // the new one.
+ std::cout << " Starting renegotiation";
+
+ // Create the new data socket.
+ boost::shared_ptr<udp::socket> new_data_socket(
+ new udp::socket(io_context, udp::endpoint(udp::v4(), 0)));
+
+ // Determine the new port we will use to receive data.
+ udp::endpoint new_data_endpoint = new_data_socket->local_endpoint();
+
+ // Ask the server to switch over to the new port.
+ control_request change = control_request::change(
+ data_endpoint.port(), new_data_endpoint.port());
+ asio::error_code control_result;
+ asio::async_write(control_socket, change.to_buffers(),
+ (
+ lambda::var(control_result) = lambda::_1
+ ));
+
+ // Try to receive a frame from the server on the new data socket. If we
+ // successfully receive a frame on this new data socket we can consider
+ // the renegotation complete. In that case we will close the old data
+ // socket, which will cause any outstanding receive operation on it to be
+ // cancelled.
+ frame f1;
+ asio::error_code new_data_socket_result;
+ new_data_socket->async_receive(f1.to_buffers(),
+ (
+ // Note: lambda::_1 is the first argument to the callback handler,
+ // which in this case is the error code for the operation.
+ lambda::var(new_data_socket_result) = lambda::_1,
+ lambda::if_(!lambda::_1)
+ [
+ // We have successfully received a frame on the new data socket,
+ // so we can close the old data socket. This will cancel any
+ // outstanding receive operation on the old data socket.
+ lambda::var(data_socket) = boost::shared_ptr<udp::socket>()
+ ]
+ ));
+
+ // This loop will continue until we have successfully completed the
+ // renegotiation (i.e. received a frame on the new data socket), or some
+ // unrecoverable error occurs.
+ bool done = false;
+ while (!done)
+ {
+ // Even though we're performing a renegotation, we want to continue
+ // receiving data as smoothly as possible. Therefore we will continue to
+ // try to receive a frame from the server on the old data socket. If we
+ // receive a frame on this socket we will interrupt the io_context,
+ // print the frame, and resume waiting for the other operations to
+ // complete.
+ frame f2;
+ done = true; // Let's be optimistic.
+ if (data_socket) // Might have been closed by new_data_socket's handler.
+ {
+ data_socket->async_receive(f2.to_buffers(), 0,
+ (
+ lambda::if_(!lambda::_1)
+ [
+ // We have successfully received a frame on the old data
+ // socket. Stop the io_context so that we can print it.
+ lambda::bind(&asio::io_context::stop, &io_context),
+ lambda::var(done) = false
+ ]
+ ));
+ }
+
+ // Run the operations in parallel. This will block until all operations
+ // have finished, or until the io_context is interrupted. (No threads!)
+ io_context.restart();
+ io_context.run();
+
+ // If the io_context.run() was interrupted then we have received a frame
+ // on the old data socket. We need to keep waiting for the renegotation
+ // operations to complete.
+ if (!done)
+ {
+ if (f2.number() > last_frame_number)
+ {
+ last_frame_number = f2.number();
+ std::cout << "\n" << f2.payload();
+ }
+ }
+ }
+
+ // Since the loop has finished, we have either successfully completed
+ // the renegotation, or an error has occurred. First we'll check for
+ // errors.
+ if (control_result)
+ throw asio::system_error(control_result);
+ if (new_data_socket_result)
+ throw asio::system_error(new_data_socket_result);
+
+ // If we get here it means we have successfully started receiving data on
+ // the new data socket. This new data socket will be used from now on
+ // (until the next time we renegotiate).
+ std::cout << " Renegotiation complete";
+ data_socket = new_data_socket;
+ data_endpoint = new_data_endpoint;
+ if (f1.number() > last_frame_number)
+ {
+ last_frame_number = f1.number();
+ std::cout << "\n" << f1.payload();
+ }
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp b/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp
new file mode 100644
index 00000000000..c79bc6b49f4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp
@@ -0,0 +1,156 @@
+//
+// protocol.hpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 PORTHOPPER_PROTOCOL_HPP
+#define PORTHOPPER_PROTOCOL_HPP
+
+#include <boost/array.hpp>
+#include <asio.hpp>
+#include <cstring>
+#include <iomanip>
+#include <string>
+#include <strstream>
+
+// This request is sent by the client to the server over a TCP connection.
+// The client uses it to perform three functions:
+// - To request that data start being sent to a given port.
+// - To request that data is no longer sent to a given port.
+// - To change the target port to another.
+class control_request
+{
+public:
+ // Construct an empty request. Used when receiving.
+ control_request()
+ {
+ }
+
+ // Create a request to start sending data to a given port.
+ static const control_request start(unsigned short port)
+ {
+ return control_request(0, port);
+ }
+
+ // Create a request to stop sending data to a given port.
+ static const control_request stop(unsigned short port)
+ {
+ return control_request(port, 0);
+ }
+
+ // Create a request to change the port that data is sent to.
+ static const control_request change(
+ unsigned short old_port, unsigned short new_port)
+ {
+ return control_request(old_port, new_port);
+ }
+
+ // Get the old port. Returns 0 for start requests.
+ unsigned short old_port() const
+ {
+ std::istrstream is(data_, encoded_port_size);
+ unsigned short port = 0;
+ is >> std::setw(encoded_port_size) >> std::hex >> port;
+ return port;
+ }
+
+ // Get the new port. Returns 0 for stop requests.
+ unsigned short new_port() const
+ {
+ std::istrstream is(data_ + encoded_port_size, encoded_port_size);
+ unsigned short port = 0;
+ is >> std::setw(encoded_port_size) >> std::hex >> port;
+ return port;
+ }
+
+ // Obtain buffers for reading from or writing to a socket.
+ boost::array<asio::mutable_buffer, 1> to_buffers()
+ {
+ boost::array<asio::mutable_buffer, 1> buffers
+ = { { asio::buffer(data_) } };
+ return buffers;
+ }
+
+private:
+ // Construct with specified old and new ports.
+ control_request(unsigned short old_port_number,
+ unsigned short new_port_number)
+ {
+ std::ostrstream os(data_, control_request_size);
+ os << std::setw(encoded_port_size) << std::hex << old_port_number;
+ os << std::setw(encoded_port_size) << std::hex << new_port_number;
+ }
+
+ // The length in bytes of a control_request and its components.
+ enum
+ {
+ encoded_port_size = 4, // 16-bit port in hex.
+ control_request_size = encoded_port_size * 2
+ };
+
+ // The encoded request data.
+ char data_[control_request_size];
+};
+
+// This frame is sent from the server to subscribed clients over UDP.
+class frame
+{
+public:
+ // The maximum allowable length of the payload.
+ enum { payload_size = 32 };
+
+ // Construct an empty frame. Used when receiving.
+ frame()
+ {
+ }
+
+ // Construct a frame with specified frame number and payload.
+ frame(unsigned long frame_number, const std::string& payload_data)
+ {
+ std::ostrstream os(data_, frame_size);
+ os << std::setw(encoded_number_size) << std::hex << frame_number;
+ os << std::setw(payload_size)
+ << std::setfill(' ') << payload_data.substr(0, payload_size);
+ }
+
+ // Get the frame number.
+ unsigned long number() const
+ {
+ std::istrstream is(data_, encoded_number_size);
+ unsigned long frame_number = 0;
+ is >> std::setw(encoded_number_size) >> std::hex >> frame_number;
+ return frame_number;
+ }
+
+ // Get the payload data.
+ const std::string payload() const
+ {
+ return std::string(data_ + encoded_number_size, payload_size);
+ }
+
+ // Obtain buffers for reading from or writing to a socket.
+ boost::array<asio::mutable_buffer, 1> to_buffers()
+ {
+ boost::array<asio::mutable_buffer, 1> buffers
+ = { { asio::buffer(data_) } };
+ return buffers;
+ }
+
+private:
+ // The length in bytes of a frame and its components.
+ enum
+ {
+ encoded_number_size = 8, // Frame number in hex.
+ frame_size = encoded_number_size + payload_size
+ };
+
+ // The encoded frame data.
+ char data_[frame_size];
+};
+
+#endif // PORTHOPPER_PROTOCOL_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp b/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp
new file mode 100644
index 00000000000..b98a7d4b24d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp
@@ -0,0 +1,189 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cmath>
+#include <cstdlib>
+#include <exception>
+#include <iostream>
+#include <set>
+#include "protocol.hpp"
+
+using asio::ip::tcp;
+using asio::ip::udp;
+
+typedef boost::shared_ptr<tcp::socket> tcp_socket_ptr;
+typedef boost::shared_ptr<asio::deadline_timer> timer_ptr;
+typedef boost::shared_ptr<control_request> control_request_ptr;
+
+class server
+{
+public:
+ // Construct the server to wait for incoming control connections.
+ server(asio::io_context& io_context, unsigned short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
+ timer_(io_context),
+ udp_socket_(io_context, udp::endpoint(udp::v4(), 0)),
+ next_frame_number_(1)
+ {
+ // Start waiting for a new control connection.
+ tcp_socket_ptr new_socket(
+ new tcp::socket(acceptor_.get_executor().context()));
+ acceptor_.async_accept(*new_socket,
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error, new_socket));
+
+ // Start the timer used to generate outgoing frames.
+ timer_.expires_from_now(boost::posix_time::milliseconds(100));
+ timer_.async_wait(boost::bind(&server::handle_timer, this));
+ }
+
+ // Handle a new control connection.
+ void handle_accept(const asio::error_code& ec, tcp_socket_ptr socket)
+ {
+ if (!ec)
+ {
+ // Start receiving control requests on the connection.
+ control_request_ptr request(new control_request);
+ asio::async_read(*socket, request->to_buffers(),
+ boost::bind(&server::handle_control_request, this,
+ asio::placeholders::error, socket, request));
+ }
+
+ // Start waiting for a new control connection.
+ tcp_socket_ptr new_socket(
+ new tcp::socket(acceptor_.get_executor().context()));
+ acceptor_.async_accept(*new_socket,
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error, new_socket));
+ }
+
+ // Handle a new control request.
+ void handle_control_request(const asio::error_code& ec,
+ tcp_socket_ptr socket, control_request_ptr request)
+ {
+ if (!ec)
+ {
+ // Delay handling of the control request to simulate network latency.
+ timer_ptr delay_timer(
+ new asio::deadline_timer(acceptor_.get_executor().context()));
+ delay_timer->expires_from_now(boost::posix_time::seconds(2));
+ delay_timer->async_wait(
+ boost::bind(&server::handle_control_request_timer, this,
+ socket, request, delay_timer));
+ }
+ }
+
+ void handle_control_request_timer(tcp_socket_ptr socket,
+ control_request_ptr request, timer_ptr /*delay_timer*/)
+ {
+ // Determine what address this client is connected from, since
+ // subscriptions must be stored on the server as a complete endpoint, not
+ // just a port. We use the non-throwing overload of remote_endpoint() since
+ // it may fail if the socket is no longer connected.
+ asio::error_code ec;
+ tcp::endpoint remote_endpoint = socket->remote_endpoint(ec);
+ if (!ec)
+ {
+ // Remove old port subscription, if any.
+ if (unsigned short old_port = request->old_port())
+ {
+ udp::endpoint old_endpoint(remote_endpoint.address(), old_port);
+ subscribers_.erase(old_endpoint);
+ std::cout << "Removing subscription " << old_endpoint << std::endl;
+ }
+
+ // Add new port subscription, if any.
+ if (unsigned short new_port = request->new_port())
+ {
+ udp::endpoint new_endpoint(remote_endpoint.address(), new_port);
+ subscribers_.insert(new_endpoint);
+ std::cout << "Adding subscription " << new_endpoint << std::endl;
+ }
+ }
+
+ // Wait for next control request on this connection.
+ asio::async_read(*socket, request->to_buffers(),
+ boost::bind(&server::handle_control_request, this,
+ asio::placeholders::error, socket, request));
+ }
+
+ // Every time the timer fires we will generate a new frame and send it to all
+ // subscribers.
+ void handle_timer()
+ {
+ // Generate payload.
+ double x = next_frame_number_ * 0.2;
+ double y = std::sin(x);
+ int char_index = static_cast<int>((y + 1.0) * (frame::payload_size / 2));
+ std::string payload;
+ for (int i = 0; i < frame::payload_size; ++i)
+ payload += (i == char_index ? '*' : '.');
+
+ // Create the frame to be sent to all subscribers.
+ frame f(next_frame_number_++, payload);
+
+ // Send frame to all subscribers. We can use synchronous calls here since
+ // UDP send operations typically do not block.
+ std::set<udp::endpoint>::iterator j;
+ for (j = subscribers_.begin(); j != subscribers_.end(); ++j)
+ {
+ asio::error_code ec;
+ udp_socket_.send_to(f.to_buffers(), *j, 0, ec);
+ }
+
+ // Wait for next timeout.
+ timer_.expires_from_now(boost::posix_time::milliseconds(100));
+ timer_.async_wait(boost::bind(&server::handle_timer, this));
+ }
+
+private:
+ // The acceptor used to accept incoming control connections.
+ tcp::acceptor acceptor_;
+
+ // The timer used for generating data.
+ asio::deadline_timer timer_;
+
+ // The socket used to send data to subscribers.
+ udp::socket udp_socket_;
+
+ // The next frame number.
+ unsigned long next_frame_number_;
+
+ // The set of endpoints that are subscribed.
+ std::set<udp::endpoint> subscribers_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/serialization/.gitignore b/3rdparty/asio/src/examples/cpp03/serialization/.gitignore
new file mode 100644
index 00000000000..692ea7e7e65
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/serialization/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+client
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/serialization/client.cpp b/3rdparty/asio/src/examples/cpp03/serialization/client.cpp
new file mode 100644
index 00000000000..8b83de284f4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/serialization/client.cpp
@@ -0,0 +1,125 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include <vector>
+#include "connection.hpp" // Must come before boost/serialization headers.
+#include <boost/serialization/vector.hpp>
+#include "stock.hpp"
+
+namespace s11n_example {
+
+/// Downloads stock quote information from a server.
+class client
+{
+public:
+ /// Constructor starts the asynchronous connect operation.
+ client(asio::io_context& io_context,
+ const std::string& host, const std::string& service)
+ : connection_(io_context)
+ {
+ // Resolve the host name into an IP address.
+ asio::ip::tcp::resolver resolver(io_context);
+ asio::ip::tcp::resolver::query query(host, service);
+ asio::ip::tcp::resolver::iterator endpoint_iterator =
+ resolver.resolve(query);
+
+ // Start an asynchronous connect operation.
+ asio::async_connect(connection_.socket(), endpoint_iterator,
+ boost::bind(&client::handle_connect, this,
+ asio::placeholders::error));
+ }
+
+ /// Handle completion of a connect operation.
+ void handle_connect(const asio::error_code& e)
+ {
+ if (!e)
+ {
+ // Successfully established connection. Start operation to read the list
+ // of stocks. The connection::async_read() function will automatically
+ // decode the data that is read from the underlying socket.
+ connection_.async_read(stocks_,
+ boost::bind(&client::handle_read, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ // An error occurred. Log it and return. Since we are not starting a new
+ // operation the io_context will run out of work to do and the client will
+ // exit.
+ std::cerr << e.message() << std::endl;
+ }
+ }
+
+ /// Handle completion of a read operation.
+ void handle_read(const asio::error_code& e)
+ {
+ if (!e)
+ {
+ // Print out the data that was received.
+ for (std::size_t i = 0; i < stocks_.size(); ++i)
+ {
+ std::cout << "Stock number " << i << "\n";
+ std::cout << " code: " << stocks_[i].code << "\n";
+ std::cout << " name: " << stocks_[i].name << "\n";
+ std::cout << " open_price: " << stocks_[i].open_price << "\n";
+ std::cout << " high_price: " << stocks_[i].high_price << "\n";
+ std::cout << " low_price: " << stocks_[i].low_price << "\n";
+ std::cout << " last_price: " << stocks_[i].last_price << "\n";
+ std::cout << " buy_price: " << stocks_[i].buy_price << "\n";
+ std::cout << " buy_quantity: " << stocks_[i].buy_quantity << "\n";
+ std::cout << " sell_price: " << stocks_[i].sell_price << "\n";
+ std::cout << " sell_quantity: " << stocks_[i].sell_quantity << "\n";
+ }
+ }
+ else
+ {
+ // An error occurred.
+ std::cerr << e.message() << std::endl;
+ }
+
+ // Since we are not starting a new operation the io_context will run out of
+ // work to do and the client will exit.
+ }
+
+private:
+ /// The connection to the server.
+ connection connection_;
+
+ /// The data received from the server.
+ std::vector<stock> stocks_;
+};
+
+} // namespace s11n_example
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 3)
+ {
+ std::cerr << "Usage: client <host> <port>" << std::endl;
+ return 1;
+ }
+
+ asio::io_context io_context;
+ s11n_example::client client(io_context, argv[1], argv[2]);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/serialization/connection.hpp b/3rdparty/asio/src/examples/cpp03/serialization/connection.hpp
new file mode 100644
index 00000000000..a1fa2a19e8e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/serialization/connection.hpp
@@ -0,0 +1,188 @@
+//
+// connection.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SERIALIZATION_CONNECTION_HPP
+#define SERIALIZATION_CONNECTION_HPP
+
+#include <asio.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+
+namespace s11n_example {
+
+/// The connection class provides serialization primitives on top of a socket.
+/**
+ * Each message sent using this class consists of:
+ * @li An 8-byte header containing the length of the serialized data in
+ * hexadecimal.
+ * @li The serialized data.
+ */
+class connection
+{
+public:
+ /// Constructor.
+ connection(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ /// Get the underlying socket. Used for making a connection or for accepting
+ /// an incoming connection.
+ asio::ip::tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ /// Asynchronously write a data structure to the socket.
+ template <typename T, typename Handler>
+ void async_write(const T& t, Handler handler)
+ {
+ // Serialize the data first so we know how large it is.
+ std::ostringstream archive_stream;
+ boost::archive::text_oarchive archive(archive_stream);
+ archive << t;
+ outbound_data_ = archive_stream.str();
+
+ // Format the header.
+ std::ostringstream header_stream;
+ header_stream << std::setw(header_length)
+ << std::hex << outbound_data_.size();
+ if (!header_stream || header_stream.str().size() != header_length)
+ {
+ // Something went wrong, inform the caller.
+ asio::error_code error(asio::error::invalid_argument);
+ socket_.get_io_context().post(boost::bind(handler, error));
+ return;
+ }
+ outbound_header_ = header_stream.str();
+
+ // Write the serialized data to the socket. We use "gather-write" to send
+ // both the header and the data in a single write operation.
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(outbound_header_));
+ buffers.push_back(asio::buffer(outbound_data_));
+ asio::async_write(socket_, buffers, handler);
+ }
+
+ /// Asynchronously read a data structure from the socket.
+ template <typename T, typename Handler>
+ void async_read(T& t, Handler handler)
+ {
+ // Issue a read operation to read exactly the number of bytes in a header.
+ void (connection::*f)(
+ const asio::error_code&,
+ T&, boost::tuple<Handler>)
+ = &connection::handle_read_header<T, Handler>;
+ asio::async_read(socket_, asio::buffer(inbound_header_),
+ boost::bind(f,
+ this, asio::placeholders::error, boost::ref(t),
+ boost::make_tuple(handler)));
+ }
+
+ /// Handle a completed read of a message header. The handler is passed using
+ /// a tuple since boost::bind seems to have trouble binding a function object
+ /// created using boost::bind as a parameter.
+ template <typename T, typename Handler>
+ void handle_read_header(const asio::error_code& e,
+ T& t, boost::tuple<Handler> handler)
+ {
+ if (e)
+ {
+ boost::get<0>(handler)(e);
+ }
+ else
+ {
+ // Determine the length of the serialized data.
+ std::istringstream is(std::string(inbound_header_, header_length));
+ std::size_t inbound_data_size = 0;
+ if (!(is >> std::hex >> inbound_data_size))
+ {
+ // Header doesn't seem to be valid. Inform the caller.
+ asio::error_code error(asio::error::invalid_argument);
+ boost::get<0>(handler)(error);
+ return;
+ }
+
+ // Start an asynchronous call to receive the data.
+ inbound_data_.resize(inbound_data_size);
+ void (connection::*f)(
+ const asio::error_code&,
+ T&, boost::tuple<Handler>)
+ = &connection::handle_read_data<T, Handler>;
+ asio::async_read(socket_, asio::buffer(inbound_data_),
+ boost::bind(f, this,
+ asio::placeholders::error, boost::ref(t), handler));
+ }
+ }
+
+ /// Handle a completed read of message data.
+ template <typename T, typename Handler>
+ void handle_read_data(const asio::error_code& e,
+ T& t, boost::tuple<Handler> handler)
+ {
+ if (e)
+ {
+ boost::get<0>(handler)(e);
+ }
+ else
+ {
+ // Extract the data structure from the data just received.
+ try
+ {
+ std::string archive_data(&inbound_data_[0], inbound_data_.size());
+ std::istringstream archive_stream(archive_data);
+ boost::archive::text_iarchive archive(archive_stream);
+ archive >> t;
+ }
+ catch (std::exception& e)
+ {
+ // Unable to decode data.
+ asio::error_code error(asio::error::invalid_argument);
+ boost::get<0>(handler)(error);
+ return;
+ }
+
+ // Inform caller that data has been received ok.
+ boost::get<0>(handler)(e);
+ }
+ }
+
+private:
+ /// The underlying socket.
+ asio::ip::tcp::socket socket_;
+
+ /// The size of a fixed length header.
+ enum { header_length = 8 };
+
+ /// Holds an outbound header.
+ std::string outbound_header_;
+
+ /// Holds the outbound data.
+ std::string outbound_data_;
+
+ /// Holds an inbound header.
+ char inbound_header_[header_length];
+
+ /// Holds the inbound data.
+ std::vector<char> inbound_data_;
+};
+
+typedef boost::shared_ptr<connection> connection_ptr;
+
+} // namespace s11n_example
+
+#endif // SERIALIZATION_CONNECTION_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/serialization/server.cpp b/3rdparty/asio/src/examples/cpp03/serialization/server.cpp
new file mode 100644
index 00000000000..b81b1a424da
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/serialization/server.cpp
@@ -0,0 +1,123 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <vector>
+#include "connection.hpp" // Must come before boost/serialization headers.
+#include <boost/serialization/vector.hpp>
+#include "stock.hpp"
+
+namespace s11n_example {
+
+/// Serves stock quote information to any client that connects to it.
+class server
+{
+public:
+ /// Constructor opens the acceptor and starts waiting for the first incoming
+ /// connection.
+ server(asio::io_context& io_context, unsigned short port)
+ : acceptor_(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port))
+ {
+ // Create the data to be sent to each client.
+ stock s;
+ s.code = "ABC";
+ s.name = "A Big Company";
+ s.open_price = 4.56;
+ s.high_price = 5.12;
+ s.low_price = 4.33;
+ s.last_price = 4.98;
+ s.buy_price = 4.96;
+ s.buy_quantity = 1000;
+ s.sell_price = 4.99;
+ s.sell_quantity = 2000;
+ stocks_.push_back(s);
+ s.code = "DEF";
+ s.name = "Developer Entertainment Firm";
+ s.open_price = 20.24;
+ s.high_price = 22.88;
+ s.low_price = 19.50;
+ s.last_price = 19.76;
+ s.buy_price = 19.72;
+ s.buy_quantity = 34000;
+ s.sell_price = 19.85;
+ s.sell_quantity = 45000;
+ stocks_.push_back(s);
+
+ // Start an accept operation for a new connection.
+ connection_ptr new_conn(new connection(acceptor_.get_io_context()));
+ acceptor_.async_accept(new_conn->socket(),
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error, new_conn));
+ }
+
+ /// Handle completion of a accept operation.
+ void handle_accept(const asio::error_code& e, connection_ptr conn)
+ {
+ if (!e)
+ {
+ // Successfully accepted a new connection. Send the list of stocks to the
+ // client. The connection::async_write() function will automatically
+ // serialize the data structure for us.
+ conn->async_write(stocks_,
+ boost::bind(&server::handle_write, this,
+ asio::placeholders::error, conn));
+ }
+
+ // Start an accept operation for a new connection.
+ connection_ptr new_conn(new connection(acceptor_.get_io_context()));
+ acceptor_.async_accept(new_conn->socket(),
+ boost::bind(&server::handle_accept, this,
+ asio::placeholders::error, new_conn));
+ }
+
+ /// Handle completion of a write operation.
+ void handle_write(const asio::error_code& e, connection_ptr conn)
+ {
+ // Nothing to do. The socket will be closed automatically when the last
+ // reference to the connection object goes away.
+ }
+
+private:
+ /// The acceptor object used to accept incoming socket connections.
+ asio::ip::tcp::acceptor acceptor_;
+
+ /// The data to be sent to each client.
+ std::vector<stock> stocks_;
+};
+
+} // namespace s11n_example
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 2)
+ {
+ std::cerr << "Usage: server <port>" << std::endl;
+ return 1;
+ }
+ unsigned short port = boost::lexical_cast<unsigned short>(argv[1]);
+
+ asio::io_context io_context;
+ s11n_example::server server(io_context, port);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/serialization/stock.hpp b/3rdparty/asio/src/examples/cpp03/serialization/stock.hpp
new file mode 100644
index 00000000000..1acbca5a7a6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/serialization/stock.hpp
@@ -0,0 +1,50 @@
+//
+// stock.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SERIALIZATION_STOCK_HPP
+#define SERIALIZATION_STOCK_HPP
+
+#include <string>
+
+namespace s11n_example {
+
+/// Structure to hold information about a single stock.
+struct stock
+{
+ std::string code;
+ std::string name;
+ double open_price;
+ double high_price;
+ double low_price;
+ double last_price;
+ double buy_price;
+ int buy_quantity;
+ double sell_price;
+ int sell_quantity;
+
+ template <typename Archive>
+ void serialize(Archive& ar, const unsigned int version)
+ {
+ ar & code;
+ ar & name;
+ ar & open_price;
+ ar & high_price;
+ ar & low_price;
+ ar & last_price;
+ ar & buy_price;
+ ar & buy_quantity;
+ ar & sell_price;
+ ar & sell_quantity;
+ }
+};
+
+} // namespace s11n_example
+
+#endif // SERIALIZATION_STOCK_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/services/.gitignore b/3rdparty/asio/src/examples/cpp03/services/.gitignore
new file mode 100644
index 00000000000..701b1b85834
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
+log.txt
diff --git a/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp b/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp
new file mode 100644
index 00000000000..876086a2ecf
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/basic_logger.hpp
@@ -0,0 +1,83 @@
+//
+// basic_logger.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SERVICES_BASIC_LOGGER_HPP
+#define SERVICES_BASIC_LOGGER_HPP
+
+#include <asio.hpp>
+#include <boost/noncopyable.hpp>
+#include <string>
+
+namespace services {
+
+/// Class to provide simple logging functionality. Use the services::logger
+/// typedef.
+template <typename Service>
+class basic_logger
+ : private boost::noncopyable
+{
+public:
+ /// The type of the service that will be used to provide timer operations.
+ typedef Service service_type;
+
+ /// The native implementation type of the timer.
+ typedef typename service_type::impl_type impl_type;
+
+ /// Constructor.
+ /**
+ * This constructor creates a logger.
+ *
+ * @param io_context The io_context object used to locate the logger service.
+ *
+ * @param identifier An identifier for this logger.
+ */
+ explicit basic_logger(asio::io_context& io_context,
+ const std::string& identifier)
+ : service_(asio::use_service<Service>(io_context)),
+ impl_(service_.null())
+ {
+ service_.create(impl_, identifier);
+ }
+
+ /// Destructor.
+ ~basic_logger()
+ {
+ service_.destroy(impl_);
+ }
+
+ /// Get the io_context associated with the object.
+ asio::io_context& get_io_context()
+ {
+ return service_.get_io_context();
+ }
+
+ /// Set the output file for all logger instances.
+ void use_file(const std::string& file)
+ {
+ service_.use_file(impl_, file);
+ }
+
+ /// Log a message.
+ void log(const std::string& message)
+ {
+ service_.log(impl_, message);
+ }
+
+private:
+ /// The backend service implementation.
+ service_type& service_;
+
+ /// The underlying native implementation.
+ impl_type impl_;
+};
+
+} // namespace services
+
+#endif // SERVICES_BASIC_LOGGER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp b/3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp
new file mode 100644
index 00000000000..e0a6af9df6f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/daytime_client.cpp
@@ -0,0 +1,97 @@
+//
+// daytime_client.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include "logger.hpp"
+
+using asio::ip::tcp;
+
+char read_buffer[1024];
+
+void read_handler(const asio::error_code& e,
+ std::size_t bytes_transferred, tcp::socket* s)
+{
+ if (!e)
+ {
+ std::cout.write(read_buffer, bytes_transferred);
+
+ s->async_read_some(asio::buffer(read_buffer),
+ boost::bind(read_handler, asio::placeholders::error,
+ asio::placeholders::bytes_transferred, s));
+ }
+ else
+ {
+ services::logger logger(s->get_executor().context(), "read_handler");
+
+ std::string msg = "Read error: ";
+ msg += e.message();
+ logger.log(msg);
+ }
+}
+
+void connect_handler(const asio::error_code& e, tcp::socket* s)
+{
+ services::logger logger(s->get_executor().context(), "connect_handler");
+
+ if (!e)
+ {
+ logger.log("Connection established");
+
+ s->async_read_some(asio::buffer(read_buffer),
+ boost::bind(read_handler, asio::placeholders::error,
+ asio::placeholders::bytes_transferred, s));
+ }
+ else
+ {
+ std::string msg = "Unable to establish connection: ";
+ msg += e.message();
+ logger.log(msg);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: daytime_client <host>" << std::endl;
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ // Set the name of the file that all logger instances will use.
+ services::logger logger(io_context, "");
+ logger.use_file("log.txt");
+
+ // Resolve the address corresponding to the given host.
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints =
+ resolver.resolve(argv[1], "daytime");
+
+ // Start an asynchronous connect.
+ tcp::socket socket(io_context);
+ asio::async_connect(socket, endpoints,
+ boost::bind(connect_handler,
+ asio::placeholders::error, &socket));
+
+ // Run the io_context until all operations have finished.
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/services/logger.hpp b/3rdparty/asio/src/examples/cpp03/services/logger.hpp
new file mode 100644
index 00000000000..41d17e6de10
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/logger.hpp
@@ -0,0 +1,24 @@
+//
+// logger.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SERVICES_LOGGER_HPP
+#define SERVICES_LOGGER_HPP
+
+#include "basic_logger.hpp"
+#include "logger_service.hpp"
+
+namespace services {
+
+/// Typedef for typical logger usage.
+typedef basic_logger<logger_service> logger;
+
+} // namespace services
+
+#endif // SERVICES_LOGGER_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/services/logger_service.cpp b/3rdparty/asio/src/examples/cpp03/services/logger_service.cpp
new file mode 100644
index 00000000000..c3543e47f5a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/logger_service.cpp
@@ -0,0 +1,17 @@
+//
+// logger_service.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "logger_service.hpp"
+
+namespace services {
+
+asio::io_context::id logger_service::id;
+
+} // namespace services
diff --git a/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp b/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp
new file mode 100644
index 00000000000..9f175dffba3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/services/logger_service.hpp
@@ -0,0 +1,145 @@
+//
+// logger_service.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SERVICES_LOGGER_SERVICE_HPP
+#define SERVICES_LOGGER_SERVICE_HPP
+
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+namespace services {
+
+/// Service implementation for the logger.
+class logger_service
+ : public asio::io_context::service
+{
+public:
+ /// The unique service identifier.
+ static asio::io_context::id id;
+
+ /// The backend implementation of a logger.
+ struct logger_impl
+ {
+ explicit logger_impl(const std::string& ident) : identifier(ident) {}
+ std::string identifier;
+ };
+
+ /// The type for an implementation of the logger.
+ typedef logger_impl* impl_type;
+
+ /// Constructor creates a thread to run a private io_context.
+ logger_service(asio::io_context& io_context)
+ : asio::io_context::service(io_context),
+ work_io_context_(),
+ work_(asio::make_work_guard(work_io_context_)),
+ work_thread_(new asio::thread(
+ boost::bind(&asio::io_context::run, &work_io_context_)))
+ {
+ }
+
+ /// Destructor shuts down the private io_context.
+ ~logger_service()
+ {
+ /// Indicate that we have finished with the private io_context. Its
+ /// io_context::run() function will exit once all other work has completed.
+ work_.reset();
+ if (work_thread_)
+ work_thread_->join();
+ }
+
+ /// Destroy all user-defined handler objects owned by the service.
+ void shutdown_service()
+ {
+ }
+
+ /// Return a null logger implementation.
+ impl_type null() const
+ {
+ return 0;
+ }
+
+ /// Create a new logger implementation.
+ void create(impl_type& impl, const std::string& identifier)
+ {
+ impl = new logger_impl(identifier);
+ }
+
+ /// Destroy a logger implementation.
+ void destroy(impl_type& impl)
+ {
+ delete impl;
+ impl = null();
+ }
+
+ /// Set the output file for the logger. The current implementation sets the
+ /// output file for all logger instances, and so the impl parameter is not
+ /// actually needed. It is retained here to illustrate how service functions
+ /// are typically defined.
+ void use_file(impl_type& /*impl*/, const std::string& file)
+ {
+ // Pass the work of opening the file to the background thread.
+ asio::post(work_io_context_, boost::bind(
+ &logger_service::use_file_impl, this, file));
+ }
+
+ /// Log a message.
+ void log(impl_type& impl, const std::string& message)
+ {
+ // Format the text to be logged.
+ std::ostringstream os;
+ os << impl->identifier << ": " << message;
+
+ // Pass the work of opening the file to the background thread.
+ asio::post(work_io_context_, boost::bind(
+ &logger_service::log_impl, this, os.str()));
+ }
+
+private:
+ /// Helper function used to open the output file from within the private
+ /// io_context's thread.
+ void use_file_impl(const std::string& file)
+ {
+ ofstream_.close();
+ ofstream_.clear();
+ ofstream_.open(file.c_str());
+ }
+
+ /// Helper function used to log a message from within the private io_context's
+ /// thread.
+ void log_impl(const std::string& text)
+ {
+ ofstream_ << text << std::endl;
+ }
+
+ /// Private io_context used for performing logging operations.
+ asio::io_context work_io_context_;
+
+ /// Work for the private io_context to perform. If we do not give the
+ /// io_context some work to do then the io_context::run() function will exit
+ /// immediately.
+ asio::executor_work_guard<
+ asio::io_context::executor_type> work_;
+
+ /// Thread used for running the work io_context's run loop.
+ boost::scoped_ptr<asio::thread> work_thread_;
+
+ /// The file to which log messages will be written.
+ std::ofstream ofstream_;
+};
+
+} // namespace services
+
+#endif // SERVICES_LOGGER_SERVICE_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/socks4/.gitignore b/3rdparty/asio/src/examples/cpp03/socks4/.gitignore
new file mode 100644
index 00000000000..e11e0de344e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/socks4/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+sync_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp b/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp
new file mode 100644
index 00000000000..c5558756558
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp
@@ -0,0 +1,144 @@
+//
+// socks4.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 SOCKS4_HPP
+#define SOCKS4_HPP
+
+#include <string>
+#include <asio.hpp>
+#include <boost/array.hpp>
+
+namespace socks4 {
+
+const unsigned char version = 0x04;
+
+class request
+{
+public:
+ enum command_type
+ {
+ connect = 0x01,
+ bind = 0x02
+ };
+
+ request(command_type cmd, const asio::ip::tcp::endpoint& endpoint,
+ const std::string& user_id)
+ : version_(version),
+ command_(cmd),
+ user_id_(user_id),
+ null_byte_(0)
+ {
+ // Only IPv4 is supported by the SOCKS 4 protocol.
+ if (endpoint.protocol() != asio::ip::tcp::v4())
+ {
+ throw asio::system_error(
+ asio::error::address_family_not_supported);
+ }
+
+ // Convert port number to network byte order.
+ unsigned short port = endpoint.port();
+ port_high_byte_ = (port >> 8) & 0xff;
+ port_low_byte_ = port & 0xff;
+
+ // Save IP address in network byte order.
+ address_ = endpoint.address().to_v4().to_bytes();
+ }
+
+ boost::array<asio::const_buffer, 7> buffers() const
+ {
+ boost::array<asio::const_buffer, 7> bufs =
+ {
+ {
+ asio::buffer(&version_, 1),
+ asio::buffer(&command_, 1),
+ asio::buffer(&port_high_byte_, 1),
+ asio::buffer(&port_low_byte_, 1),
+ asio::buffer(address_),
+ asio::buffer(user_id_),
+ asio::buffer(&null_byte_, 1)
+ }
+ };
+ return bufs;
+ }
+
+private:
+ unsigned char version_;
+ unsigned char command_;
+ unsigned char port_high_byte_;
+ unsigned char port_low_byte_;
+ asio::ip::address_v4::bytes_type address_;
+ std::string user_id_;
+ unsigned char null_byte_;
+};
+
+class reply
+{
+public:
+ enum status_type
+ {
+ request_granted = 0x5a,
+ request_failed = 0x5b,
+ request_failed_no_identd = 0x5c,
+ request_failed_bad_user_id = 0x5d
+ };
+
+ reply()
+ : null_byte_(0),
+ status_()
+ {
+ }
+
+ boost::array<asio::mutable_buffer, 5> buffers()
+ {
+ boost::array<asio::mutable_buffer, 5> bufs =
+ {
+ {
+ asio::buffer(&null_byte_, 1),
+ asio::buffer(&status_, 1),
+ asio::buffer(&port_high_byte_, 1),
+ asio::buffer(&port_low_byte_, 1),
+ asio::buffer(address_)
+ }
+ };
+ return bufs;
+ }
+
+ bool success() const
+ {
+ return null_byte_ == 0 && status_ == request_granted;
+ }
+
+ unsigned char status() const
+ {
+ return status_;
+ }
+
+ asio::ip::tcp::endpoint endpoint() const
+ {
+ unsigned short port = port_high_byte_;
+ port = (port << 8) & 0xff00;
+ port = port | port_low_byte_;
+
+ asio::ip::address_v4 address(address_);
+
+ return asio::ip::tcp::endpoint(address, port);
+ }
+
+private:
+ unsigned char null_byte_;
+ unsigned char status_;
+ unsigned char port_high_byte_;
+ unsigned char port_low_byte_;
+ asio::ip::address_v4::bytes_type address_;
+};
+
+} // namespace socks4
+
+#endif // SOCKS4_HPP
diff --git a/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp b/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp
new file mode 100644
index 00000000000..7b82564ab53
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp
@@ -0,0 +1,94 @@
+//
+// sync_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <iomanip>
+#include <ostream>
+#include <string>
+#include <asio.hpp>
+#include <boost/array.hpp>
+#include "socks4.hpp"
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 4)
+ {
+ std::cout << "Usage: sync_client <socks4server> <socks4port> <user>\n";
+ std::cout << "Examples:\n";
+ std::cout << " sync_client 127.0.0.1 1080 chris\n";
+ std::cout << " sync_client localhost socks chris\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ // Get a list of endpoints corresponding to the SOCKS 4 server name.
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
+
+ // Try each endpoint until we successfully establish a connection to the
+ // SOCKS 4 server.
+ tcp::socket socket(io_context);
+ asio::connect(socket, endpoints);
+
+ // Get an endpoint for the Boost website. This will be passed to the SOCKS
+ // 4 server. Explicitly specify IPv4 since SOCKS 4 does not support IPv6.
+ tcp::endpoint http_endpoint =
+ *resolver.resolve(tcp::v4(), "www.boost.org", "http").begin();
+
+ // Send the request to the SOCKS 4 server.
+ socks4::request socks_request(
+ socks4::request::connect, http_endpoint, argv[3]);
+ asio::write(socket, socks_request.buffers());
+
+ // Receive a response from the SOCKS 4 server.
+ socks4::reply socks_reply;
+ asio::read(socket, socks_reply.buffers());
+
+ // Check whether we successfully negotiated with the SOCKS 4 server.
+ if (!socks_reply.success())
+ {
+ std::cout << "Connection failed.\n";
+ std::cout << "status = 0x" << std::hex << socks_reply.status();
+ return 1;
+ }
+
+ // Form the HTTP request. We specify the "Connection: close" header so that
+ // the server will close the socket after transmitting the response. This
+ // will allow us to treat all data up until the EOF as the response.
+ std::string request =
+ "GET / HTTP/1.0\r\n"
+ "Host: www.boost.org\r\n"
+ "Accept: */*\r\n"
+ "Connection: close\r\n\r\n";
+
+ // Send the HTTP request.
+ asio::write(socket, asio::buffer(request));
+
+ // Read until EOF, writing data to output as we go.
+ boost::array<char, 512> response;
+ asio::error_code error;
+ while (std::size_t s = socket.read_some(
+ asio::buffer(response), error))
+ std::cout.write(response.data(), s);
+ if (error != asio::error::eof)
+ throw asio::system_error(error);
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/spawn/.gitignore b/3rdparty/asio/src/examples/cpp03/spawn/.gitignore
new file mode 100644
index 00000000000..6b8a121e099
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/spawn/.gitignore
@@ -0,0 +1,12 @@
+.deps
+.dirstamp
+parallel_grep
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/spawn/echo_server.cpp b/3rdparty/asio/src/examples/cpp03/spawn/echo_server.cpp
new file mode 100644
index 00000000000..415f6da8f33
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/spawn/echo_server.cpp
@@ -0,0 +1,122 @@
+//
+// echo_server.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/deadline_timer.hpp>
+#include <asio/io_context.hpp>
+#include <asio/ip/tcp.hpp>
+#include <asio/spawn.hpp>
+#include <asio/write.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <iostream>
+
+using asio::ip::tcp;
+
+class session : public boost::enable_shared_from_this<session>
+{
+public:
+ explicit session(asio::io_context& io_context)
+ : strand_(io_context),
+ socket_(io_context),
+ timer_(io_context)
+ {
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void go()
+ {
+ asio::spawn(strand_,
+ boost::bind(&session::echo,
+ shared_from_this(), _1));
+ asio::spawn(strand_,
+ boost::bind(&session::timeout,
+ shared_from_this(), _1));
+ }
+
+private:
+ void echo(asio::yield_context yield)
+ {
+ try
+ {
+ char data[128];
+ for (;;)
+ {
+ timer_.expires_from_now(boost::posix_time::seconds(10));
+ std::size_t n = socket_.async_read_some(asio::buffer(data), yield);
+ asio::async_write(socket_, asio::buffer(data, n), yield);
+ }
+ }
+ catch (std::exception& e)
+ {
+ socket_.close();
+ timer_.cancel();
+ }
+ }
+
+ void timeout(asio::yield_context yield)
+ {
+ while (socket_.is_open())
+ {
+ asio::error_code ignored_ec;
+ timer_.async_wait(yield[ignored_ec]);
+ if (timer_.expires_from_now() <= boost::posix_time::seconds(0))
+ socket_.close();
+ }
+ }
+
+ asio::io_context::strand strand_;
+ tcp::socket socket_;
+ asio::deadline_timer timer_;
+};
+
+void do_accept(asio::io_context& io_context,
+ unsigned short port, asio::yield_context yield)
+{
+ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
+
+ for (;;)
+ {
+ asio::error_code ec;
+ boost::shared_ptr<session> new_session(new session(io_context));
+ acceptor.async_accept(new_session->socket(), yield[ec]);
+ if (!ec) new_session->go();
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ asio::spawn(io_context,
+ boost::bind(do_accept,
+ boost::ref(io_context), atoi(argv[1]), _1));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/spawn/parallel_grep.cpp b/3rdparty/asio/src/examples/cpp03/spawn/parallel_grep.cpp
new file mode 100644
index 00000000000..d742f196d78
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/spawn/parallel_grep.cpp
@@ -0,0 +1,89 @@
+//
+// parallel_grep.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/dispatch.hpp>
+#include <asio/post.hpp>
+#include <asio/spawn.hpp>
+#include <asio/strand.hpp>
+#include <asio/thread_pool.hpp>
+#include <boost/bind.hpp>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+using asio::dispatch;
+using asio::spawn;
+using asio::strand;
+using asio::thread_pool;
+using asio::yield_context;
+
+void print_match(std::string input_file, std::string line)
+{
+ std::cout << input_file << ':' << line << std::endl;
+}
+
+void search_file(std::string search_string, std::string input_file,
+ strand<thread_pool::executor_type> output_strand, yield_context yield)
+{
+ std::ifstream is(input_file.c_str());
+ std::string line;
+ std::size_t line_num = 0;
+ while (std::getline(is, line))
+ {
+ // If we find a match, send a message to the output.
+ if (line.find(search_string) != std::string::npos)
+ {
+ dispatch(output_strand, boost::bind(&print_match, input_file, line));
+ }
+
+ // Every so often we yield control to another coroutine.
+ if (++line_num % 10 == 0)
+ post(yield);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc < 2)
+ {
+ std::cerr << "Usage: parallel_grep <string> <files...>\n";
+ return 1;
+ }
+
+ // We use a fixed size pool of threads for reading the input files. The
+ // number of threads is automatically determined based on the number of
+ // CPUs available in the system.
+ thread_pool pool;
+
+ // To prevent the output from being garbled, we use a strand to synchronise
+ // printing.
+ strand<thread_pool::executor_type> output_strand(pool.get_executor());
+
+ // Spawn a new coroutine for each file specified on the command line.
+ std::string search_string = argv[1];
+ for (int argn = 2; argn < argc; ++argn)
+ {
+ std::string input_file = argv[argn];
+ spawn(pool, boost::bind(&search_file,
+ search_string, input_file, output_strand, _1));
+ }
+
+ // Join the thread pool to wait for all the spawned tasks to complete.
+ pool.join();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/.gitignore b/3rdparty/asio/src/examples/cpp03/ssl/.gitignore
new file mode 100644
index 00000000000..a67811253d9
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+server
+client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/README b/3rdparty/asio/src/examples/cpp03/ssl/README
new file mode 100644
index 00000000000..8d94105be5b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/README
@@ -0,0 +1,8 @@
+The passphrase for both the CA and server private keys is "test".
+
+
+-------------------------------------------------------------------------------
+Copyright (c) 2003-2016 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)
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/ca.pem b/3rdparty/asio/src/examples/cpp03/ssl/ca.pem
new file mode 100644
index 00000000000..1ee5f2ca43b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/ca.pem
@@ -0,0 +1,49 @@
+-----BEGIN CERTIFICATE-----
+MIIDlzCCAn+gAwIBAgIJAMJYU3U6A0IRMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
+BAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChME
+YXNpbzAeFw0xNTExMTgyMjMzNDhaFw0yMDExMTYyMjMzNDhaMDsxCzAJBgNVBAYT
+AkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChMEYXNp
+bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcRJocHdVMdLUJ/pypY
+QVSTC0t3IIgjwjazrK3kAaoIMvzPmDFxEXWcDx+nyz8kQ/E38Ir/ef2BCNGci5hu
+wkfMSuMoW9l2N4hx3QCcF46tTDEZztFxWAH7QbE2wYMlMgKZSxWimNfq0YjxEEXb
+QM0lGPLFh7Xoko29H0F3LKaaQV9u/vop3Hs0h12HeWlY4PiLp7QQTNGqbWcXycA0
+NZ/fyismireyEvPAgo6L8iXuAi7g0TVKVNlrticGGjMcMq6IMvxzEpSMkuMQ5rWj
+pZjWOoBjSYBuXdblcBRvXhOr2Ws8jJLMZfehKq9q1reQfoGV6xMnbwmumSXbWRWT
+0vkCAwEAAaOBnTCBmjAdBgNVHQ4EFgQUK/Zv/AVtfIeucJw8VEtux1dhI1YwawYD
+VR0jBGQwYoAUK/Zv/AVtfIeucJw8VEtux1dhI1ahP6Q9MDsxCzAJBgNVBAYTAkFV
+MQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChMEYXNpb4IJ
+AMJYU3U6A0IRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABLYXimq
+v/HLyIJi7Xn8AJUsICj8LKF/J24nwwiF+ibf7UkoChJURs4nN78bod/lpDVPTEVl
+gTBdV/vBJs416sCEFfsGjqB9OBYj4gb0VaJDsQd0+NMvXp0faKv2y9wgScxG9/cg
+aM7eRmyfMn1qjb6tpNxVOPpe/nFi8Vx/1orejBRaZr4zF5TkoPepfwLWQeXDUIdE
++QHZ60jZAkR5RXTVU4u3kOKcJs839pmJYyxM4H2VxpR18vy4/YdIVWkREIUM2OgT
+5iznIQIIgR56QRGP85uef+I6n0BHzrBk6du69bkQFxrFjLVGlal4bIQqSg4KGWgx
+dEdymMWzmMxpO9s=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEAxxEmhwd1Ux0tQn+nKlhBVJMLS3cgiCPCNrOsreQBqggy/M+Y
+MXERdZwPH6fLPyRD8Tfwiv95/YEI0ZyLmG7CR8xK4yhb2XY3iHHdAJwXjq1MMRnO
+0XFYAftBsTbBgyUyAplLFaKY1+rRiPEQRdtAzSUY8sWHteiSjb0fQXcspppBX27+
++incezSHXYd5aVjg+IuntBBM0aptZxfJwDQ1n9/KKyaKt7IS88CCjovyJe4CLuDR
+NUpU2Wu2JwYaMxwyrogy/HMSlIyS4xDmtaOlmNY6gGNJgG5d1uVwFG9eE6vZazyM
+ksxl96Eqr2rWt5B+gZXrEydvCa6ZJdtZFZPS+QIDAQABAoIBAQCOma+SvPoDzvvU
+DiPOxqgOEMPfjHfGbm86xl0luBalGfiEd6WbjVanfGKtF4MWOUFec+chez+FJMEP
+fufVC0qrKiJfNVMOpYvEd2SMgkSx1VymM8me6WXVDYsSipn2+1cm228ZEYAR9Emj
+oqQ4loaGLlP/3RaJbhBF7ruMJvXaZZQ4fZy74Z4tyRaaE1B659ua7Rjne7eNhQE8
+cR7cQDkxsNNN3LTbfLRwEc/gcDXWgLe5JlR/K4ZrdKc3lyivm+Uew3ubKs+fgkyY
+kHmuI3RJGIjpnsZW0/So+pHm3b/fo6lmlhTXtNNd+tkkKn2K9ttbXT3Sc13Pc+4w
+c4MLyUpdAoGBAOxTtGDpeF6U4s+GPuOCzHCwKQyzfOyCL/UTZv1UJX7Kn1FYycJH
+eOjtBRtS661cGkGd1MPfjdX2VV84AmBGDUmRqJ2KfTI1NjLAEJ115ANTpmSTm3lF
+UYncgbzl6aflLpjE1mgY+JTJykYeN5jhhO0r2bsdY7S+zaMCSI5NLuznAoGBANej
+aMtqLg2qKoq+fUkNBHHLXelR5dBXFnKgSrTj++H4yeW9pYbl8bK3gTF3I5+dSjHW
+DdC4+X09iPqY7p8vm8Gq/vgO8Bu+EnKNVr80PJSj7AzFGd6mk/CVrAzoY2XJWbAp
+YFwpo1WfHjS5wBfQzBlXY7kWVB7fj32kk14PYmUfAoGBAJXfd7NGHPoOfdCSGGv8
+VV7ZuQ6+/WiYH4XS6iuaI7VHFsZmAn3dCcbeGbD8Y04r7NLUH0yhB7g7YmTihk87
+3c1cPIy8eS1QJbEFsQPK8fFSKWH7YkwEM/O0DesX+5hodaaYnkiiHXNujYLuQuAH
+lV87wfcyajsEDjFkj1L/i9TdAoGBAKYfRUQv8HqmdU+doHb+iEYCHb75UMpHzQtR
+YTwpxoo3V5Kdnz9lNeYwaF7rIY59ZgMunEYHumw5U6V625nW228/hF0lZOR6cUu+
+hu2WGHWKMvdDgMJ+IcpeA8WN4cUwcN+9gHZ/vUzg4CxOTSYLvLBpGnIkOXnvUGPC
+vaTgxTSRAoGBAOHcuZ9hcUrPuVI1HVkjQQLu5mLZ3tz6linEbe/RCdJMK8JrRX4w
+ubB7gFclMYGbLlDNAJVYkydJaCy/2NAI3rfsOda+VmDqGx6z4BbSGceHhomyU1Oo
+1H7YaXsuzDkzl23HRsyp0pKJpTdghZdbVsGF8vAB8ygK3ehM233neSln
+-----END RSA PRIVATE KEY-----
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/client.cpp b/3rdparty/asio/src/examples/cpp03/ssl/client.cpp
new file mode 100644
index 00000000000..02a3ce8b3ca
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/client.cpp
@@ -0,0 +1,156 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+#include "asio/ssl.hpp"
+
+enum { max_length = 1024 };
+
+class client
+{
+public:
+ client(asio::io_context& io_context,
+ asio::ssl::context& context,
+ asio::ip::tcp::resolver::results_type endpoints)
+ : socket_(io_context, context)
+ {
+ socket_.set_verify_mode(asio::ssl::verify_peer);
+ socket_.set_verify_callback(
+ boost::bind(&client::verify_certificate, this, _1, _2));
+
+ asio::async_connect(socket_.lowest_layer(), endpoints,
+ boost::bind(&client::handle_connect, this,
+ asio::placeholders::error));
+ }
+
+ bool verify_certificate(bool preverified,
+ asio::ssl::verify_context& ctx)
+ {
+ // The verify callback can be used to check whether the certificate that is
+ // being presented is valid for the peer. For example, RFC 2818 describes
+ // the steps involved in doing this for HTTPS. Consult the OpenSSL
+ // documentation for more details. Note that the callback is called once
+ // for each certificate in the certificate chain, starting from the root
+ // certificate authority.
+
+ // In this example we will simply print the certificate's subject name.
+ char subject_name[256];
+ X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
+ X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
+ std::cout << "Verifying " << subject_name << "\n";
+
+ return preverified;
+ }
+
+ void handle_connect(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_handshake(asio::ssl::stream_base::client,
+ boost::bind(&client::handle_handshake, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ std::cout << "Connect failed: " << error.message() << "\n";
+ }
+ }
+
+ void handle_handshake(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ std::cout << "Enter message: ";
+ std::cin.getline(request_, max_length);
+ size_t request_length = strlen(request_);
+
+ asio::async_write(socket_,
+ asio::buffer(request_, request_length),
+ boost::bind(&client::handle_write, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ std::cout << "Handshake failed: " << error.message() << "\n";
+ }
+ }
+
+ void handle_write(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ asio::async_read(socket_,
+ asio::buffer(reply_, bytes_transferred),
+ boost::bind(&client::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ std::cout << "Write failed: " << error.message() << "\n";
+ }
+ }
+
+ void handle_read(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ std::cout << "Reply: ";
+ std::cout.write(reply_, bytes_transferred);
+ std::cout << "\n";
+ }
+ else
+ {
+ std::cout << "Read failed: " << error.message() << "\n";
+ }
+ }
+
+private:
+ asio::ssl::stream<asio::ip::tcp::socket> socket_;
+ char request_[max_length];
+ char reply_[max_length];
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::resolver resolver(io_context);
+ asio::ip::tcp::resolver::results_type endpoints =
+ resolver.resolve(argv[1], argv[2]);
+
+ asio::ssl::context ctx(asio::ssl::context::sslv23);
+ ctx.load_verify_file("ca.pem");
+
+ client c(io_context, ctx, endpoints);
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/dh2048.pem b/3rdparty/asio/src/examples/cpp03/ssl/dh2048.pem
new file mode 100644
index 00000000000..07250cca62f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/dh2048.pem
@@ -0,0 +1,8 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEAyNnxZSYc6J89mDNnqOH8bnwBiAJxcaUS3PkIEcwW8D9o2BlNq6EO
+XKMIbdfwPFZi80GMpNu3YP2A2B42sAHmb7w7ZA92QDv3JjqzR0QuS/CkMv4CEjha
+QBFwBDDWnnHBSj4w/t54ii0SH34mWcjBItI2eMtnM9J6fnvNiWqJxdt4iA4mZjZD
+qZTjIRyjgKAevzkqAlBqQRoVUUgu+9Cf29wXjVl3bE+0VU5CdFeyT+Y9yunz88mq
+rGyx1uPt+zbIfxuNLH+coY67y1ht7iZEL5WLd3wGCycRT+lYy2AL/rxGBPxStFIT
+2bOkQao6sAfb4UdGEUlwHUXZrAV51oM30wIBAg==
+-----END DH PARAMETERS-----
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/server.cpp b/3rdparty/asio/src/examples/cpp03/ssl/server.cpp
new file mode 100644
index 00000000000..ad3d73a2c44
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/server.cpp
@@ -0,0 +1,170 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/bind.hpp>
+#include "asio.hpp"
+#include "asio/ssl.hpp"
+
+typedef asio::ssl::stream<asio::ip::tcp::socket> ssl_socket;
+
+class session
+{
+public:
+ session(asio::io_context& io_context,
+ asio::ssl::context& context)
+ : socket_(io_context, context)
+ {
+ }
+
+ ssl_socket::lowest_layer_type& socket()
+ {
+ return socket_.lowest_layer();
+ }
+
+ void start()
+ {
+ socket_.async_handshake(asio::ssl::stream_base::server,
+ boost::bind(&session::handle_handshake, this,
+ asio::placeholders::error));
+ }
+
+ void handle_handshake(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+ void handle_read(const asio::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (!error)
+ {
+ asio::async_write(socket_,
+ asio::buffer(data_, bytes_transferred),
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+ void handle_write(const asio::error_code& error)
+ {
+ if (!error)
+ {
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ else
+ {
+ delete this;
+ }
+ }
+
+private:
+ ssl_socket socket_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, unsigned short port)
+ : io_context_(io_context),
+ acceptor_(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)),
+ context_(asio::ssl::context::sslv23)
+ {
+ context_.set_options(
+ asio::ssl::context::default_workarounds
+ | asio::ssl::context::no_sslv2
+ | asio::ssl::context::single_dh_use);
+ context_.set_password_callback(boost::bind(&server::get_password, this));
+ context_.use_certificate_chain_file("server.pem");
+ context_.use_private_key_file("server.pem", asio::ssl::context::pem);
+ context_.use_tmp_dh_file("dh2048.pem");
+
+ start_accept();
+ }
+
+ std::string get_password() const
+ {
+ return "test";
+ }
+
+ void start_accept()
+ {
+ session* new_session = new session(io_context_, context_);
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session* new_session,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_session->start();
+ }
+ else
+ {
+ delete new_session;
+ }
+
+ start_accept();
+ }
+
+private:
+ asio::io_context& io_context_;
+ asio::ip::tcp::acceptor acceptor_;
+ asio::ssl::context context_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/ssl/server.pem b/3rdparty/asio/src/examples/cpp03/ssl/server.pem
new file mode 100644
index 00000000000..37ea6e26715
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/ssl/server.pem
@@ -0,0 +1,71 @@
+-----BEGIN CERTIFICATE-----
+MIIDAzCCAesCCQD9QcRiWk0y9TANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB
+VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w
+HhcNMTUxMTE4MjIzNzMxWhcNMjAxMTE2MjIzNzMxWjBMMQswCQYDVQQGEwJBVTEM
+MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8xDzAN
+BgNVBAsTBnNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr0
++NXSklsGJR7HYHP/H4V5+KpYrmFKva/K7iiqi+XyWEjGnj+/iImJW26phhg9GouN
+JJxdrP7/0LwpMsEC/9v09dMNAEewtYhPgD4kiUH/E/79wVmayMZZZGrpF9Rw+wWv
+q58y3L1wKge3qilX6slVDdNhqU3vBiMKEJfsjE4PKcEVjPCjVJG2562eHK9FxyjQ
+DykyH61lQKBQOiElilPQKzAO7U36yTvs+chWuUfK47B8EC+PJ5KcLEppli4ljlwE
+w01HnGxwvjDLobKm2jL6CWi3aYGWudyTsNAd7YC5C7psktBypQLBcfp7uUrrR5Bb
+PEjFHJUWIlyoYvm2OjMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAtceVW6tixFsB
+ZRhjL5aRCcbx2iMwEXd54lcP6BWe1qOcDPHoSYI1zvvGzohbEvBfqUv78S9MtzaT
+gMe5rIU9M1ZM09PyaM6ZutGpKHE8L4qcOslTt41GQFsSqPFdcbgSV20MvBzjGayR
+AI/WV0avW3oasdetJPZCR7bRbCbMbWTgclUfv5F25ENcR+BhNuilfL15owL0s4sS
+Wb4jOOHhXV9iXeS2dH0snFqv4BmQ9ZoA7zbM9lG3EU5DuxHESYkCnzJyEqqY3vWv
+PFRViCxLp5LQLmkTQ3dglVQA4x6ZaonaewdPtdhjkLUuIqDvQx5+kIaOELbSws+c
+bREYlnGrFw==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,D459676347D389E9135496D8AAFA7953
+
+wbrjxr9NHur8kgxDsgXOY9qFGKpONIQLxkuahUrDD/H+s/l7ugsLWOPsOXbjNL/7
+QYUBAx85HKm9D8BQ5g78Y82qfArap3/3IIuysDfQDh4fQodhVtmGTFiCOvudlGEp
+lq1niQRLThlxeRoFphH8KKiOTO9a/d8tdL7zRmiFwnVnhK4014mgVmgcSefA1AF5
+RbJAeMclUKddG6ltQK00ptg84CDXiMWQXFBGGmQ1av2lyFzC+xLP+qDqZAYTM9lZ
+NFRo2oEZP1ozfOVNSbXTanJgZ0DSSmhGE1PcVrHSeE/v+k1kPh3oVKi9GV51kIDC
+Zd9f/XltuDOzy1Ybn6gRy4nzNpzcwjSCIHEdSD5nxU5JfHfQ3OtnsEab7qf989iP
+s2LbCSp5uGTMvfesMIkixIZAQp2FeahZTAgU2Vx+wi5Kks68rOqeywEfzACL/Um5
+7XZu8gDs4MgRRWnxK1BbJDPifICLvSJZvgB9FKX/hk4FHFF+MtcrkalehCuLooDV
+3rfHNvRSbg7J97XQ3QC+k9ZDaumpy6n+LhaVv7BIJRBnBBtZ5Eg3DmPg6flqaHAU
+Y/8d82wb/pCmbvR3B1/Ebgs84DPJ+uZnY9M5Iwx19oqlVSR2ts/Tx619LGAm+BiQ
+7YDoC4CFmpAA8Uw0xnUbNgx94NdNmlnLeLtS50b0XlWpHKbVzmVbNYEjY6NHMlLt
+aqxWHTYTa7g/c1bg2/nxF1Lbfu5VSTROGBUuer1c3yzVuyBrjcX92Jp4BJH78qOp
+N6lY6MnH4HYRXHjzlt/S0ZzO0faPPe18Q8SWvnDVuE3fYzzL772B56d2t8eodc+/
+t6M3qJ60eXdsmgYOaPRLRUovN2xT2UUr0+biuguHyqfaVfcEU/adw+b9oUVE+5Nw
+nZHI5qhPnhLxChyZqbBl68zMUyKlfff4OyLvRGpfcHwBw6DTGjduB+DDsqqkcIB9
+2VL6nps7ZVCwMPI18siUd6cttEOf6ZXrVqHg9wfDvJOlh2NNKNLxSAFubHc90Jlj
+KejrWenXo2w6YkSUeTV4t4cWu7U8rXIkTJXDl1S6NO8DWqNDo5KjgJ2SK5NlSOJ7
+jgECn390ooneJOxxytPVQO2xppXQZZS65RHrvhB+ss5xUknly9q+ICyt6xTR9nqA
+PKkeSE6qVY0J4JgFXpkgQxgwMnjSED3LKr3jlz28pr5cC6tsc5SSlekHjT2fcSrX
+uccaVahaJRigf+q+4XzmJtdwbZU+YWGZRVMlQLA5yzPHQHDYkPpOeYU4WReND8S4
+TZRkPHaxOZ2lKQwJB93V8Vbt2MvwRy392452a33S4TcQLaWzoOljXjmZjrp2rvRz
+prBaNe8LnO4V8Oliv+H+E0UWiWFDuI+HBy4X4O9plsbw/gk64Phl9qLiBwaX/AIR
+66FXvC/czABo9oSt2jekcMtJofYr8Gr2bsJlt5ZX+GEOxz4jMv7xvz5/L3W7jVav
+pHGIv4xfN9FrXzL47O7UuUF9xZg4Rp/fxwpgEDNZmX/3DnP0ewZQUcgUX0pdqNGQ
+YVqJXcRF7KqG2NSQFuwPESZQnxU0WzSgRyUae7xg1WKfSuN8NVAzKhOgeqlD2IAo
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDlzCCAn+gAwIBAgIJAMJYU3U6A0IRMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
+BAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChME
+YXNpbzAeFw0xNTExMTgyMjMzNDhaFw0yMDExMTYyMjMzNDhaMDsxCzAJBgNVBAYT
+AkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChMEYXNp
+bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcRJocHdVMdLUJ/pypY
+QVSTC0t3IIgjwjazrK3kAaoIMvzPmDFxEXWcDx+nyz8kQ/E38Ir/ef2BCNGci5hu
+wkfMSuMoW9l2N4hx3QCcF46tTDEZztFxWAH7QbE2wYMlMgKZSxWimNfq0YjxEEXb
+QM0lGPLFh7Xoko29H0F3LKaaQV9u/vop3Hs0h12HeWlY4PiLp7QQTNGqbWcXycA0
+NZ/fyismireyEvPAgo6L8iXuAi7g0TVKVNlrticGGjMcMq6IMvxzEpSMkuMQ5rWj
+pZjWOoBjSYBuXdblcBRvXhOr2Ws8jJLMZfehKq9q1reQfoGV6xMnbwmumSXbWRWT
+0vkCAwEAAaOBnTCBmjAdBgNVHQ4EFgQUK/Zv/AVtfIeucJw8VEtux1dhI1YwawYD
+VR0jBGQwYoAUK/Zv/AVtfIeucJw8VEtux1dhI1ahP6Q9MDsxCzAJBgNVBAYTAkFV
+MQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTENMAsGA1UEChMEYXNpb4IJ
+AMJYU3U6A0IRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABLYXimq
+v/HLyIJi7Xn8AJUsICj8LKF/J24nwwiF+ibf7UkoChJURs4nN78bod/lpDVPTEVl
+gTBdV/vBJs416sCEFfsGjqB9OBYj4gb0VaJDsQd0+NMvXp0faKv2y9wgScxG9/cg
+aM7eRmyfMn1qjb6tpNxVOPpe/nFi8Vx/1orejBRaZr4zF5TkoPepfwLWQeXDUIdE
++QHZ60jZAkR5RXTVU4u3kOKcJs839pmJYyxM4H2VxpR18vy4/YdIVWkREIUM2OgT
+5iznIQIIgR56QRGP85uef+I6n0BHzrBk6du69bkQFxrFjLVGlal4bIQqSg4KGWgx
+dEdymMWzmMxpO9s=
+-----END CERTIFICATE-----
diff --git a/3rdparty/asio/src/examples/cpp03/timeouts/.gitignore b/3rdparty/asio/src/examples/cpp03/timeouts/.gitignore
new file mode 100644
index 00000000000..dda7f39c3c2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timeouts/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp b/3rdparty/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp
new file mode 100644
index 00000000000..98b90e9a1b3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp
@@ -0,0 +1,308 @@
+//
+// async_tcp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio/deadline_timer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/read_until.hpp"
+#include "asio/streambuf.hpp"
+#include "asio/write.hpp"
+#include <boost/bind.hpp>
+#include <iostream>
+
+using asio::deadline_timer;
+using asio::ip::tcp;
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Some asynchronous operations are given deadlines by which they must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+// +----------------+
+// | |
+// | check_deadline |<---+
+// | | |
+// +----------------+ | async_wait()
+// | |
+// +---------+
+//
+// If the deadline actor determines that the deadline has expired, the socket
+// is closed and any outstanding operations are consequently cancelled.
+//
+// Connection establishment involves trying each endpoint in turn until a
+// connection is successful, or the available endpoints are exhausted. If the
+// deadline actor closes the socket, the connect actor is woken up and moves to
+// the next endpoint.
+//
+// +---------------+
+// | |
+// | start_connect |<---+
+// | | |
+// +---------------+ |
+// | |
+// async_- | +----------------+
+// connect() | | |
+// +--->| handle_connect |
+// | |
+// +----------------+
+// :
+// Once a connection is :
+// made, the connect :
+// actor forks in two - :
+// :
+// an actor for reading : and an actor for
+// inbound messages: : sending heartbeats:
+// :
+// +------------+ : +-------------+
+// | |<- - - - -+- - - - ->| |
+// | start_read | | start_write |<---+
+// | |<---+ | | |
+// +------------+ | +-------------+ | async_wait()
+// | | | |
+// async_- | +-------------+ async_- | +--------------+
+// read_- | | | write() | | |
+// until() +--->| handle_read | +--->| handle_write |
+// | | | |
+// +-------------+ +--------------+
+//
+// The input actor reads messages from the socket, where messages are delimited
+// by the newline character. The deadline for a complete message is 30 seconds.
+//
+// The heartbeat actor sends a heartbeat (a message that consists of a single
+// newline character) every 10 seconds. In this example, no deadline is applied
+// message sending.
+//
+class client
+{
+public:
+ client(asio::io_context& io_context)
+ : stopped_(false),
+ socket_(io_context),
+ deadline_(io_context),
+ heartbeat_timer_(io_context)
+ {
+ }
+
+ // Called by the user of the client class to initiate the connection process.
+ // The endpoints will have been obtained using a tcp::resolver.
+ void start(tcp::resolver::results_type endpoints)
+ {
+ // Start the connect actor.
+ endpoints_ = endpoints;
+ start_connect(endpoints_.begin());
+
+ // Start the deadline actor. You will note that we're not setting any
+ // particular deadline here. Instead, the connect and input actors will
+ // update the deadline prior to each asynchronous operation.
+ deadline_.async_wait(boost::bind(&client::check_deadline, this));
+ }
+
+ // This function terminates all the actors to shut down the connection. It
+ // may be called by the user of the client class, or by the class itself in
+ // response to graceful termination or an unrecoverable error.
+ void stop()
+ {
+ stopped_ = true;
+ asio::error_code ignored_ec;
+ socket_.close(ignored_ec);
+ deadline_.cancel();
+ heartbeat_timer_.cancel();
+ }
+
+private:
+ void start_connect(tcp::resolver::results_type::iterator endpoint_iter)
+ {
+ if (endpoint_iter != endpoints_.end())
+ {
+ std::cout << "Trying " << endpoint_iter->endpoint() << "...\n";
+
+ // Set a deadline for the connect operation.
+ deadline_.expires_from_now(boost::posix_time::seconds(60));
+
+ // Start the asynchronous connect operation.
+ socket_.async_connect(endpoint_iter->endpoint(),
+ boost::bind(&client::handle_connect,
+ this, _1, endpoint_iter));
+ }
+ else
+ {
+ // There are no more endpoints to try. Shut down the client.
+ stop();
+ }
+ }
+
+ void handle_connect(const asio::error_code& ec,
+ tcp::resolver::results_type::iterator endpoint_iter)
+ {
+ if (stopped_)
+ return;
+
+ // The async_connect() function automatically opens the socket at the start
+ // of the asynchronous operation. If the socket is closed at this time then
+ // the timeout handler must have run first.
+ if (!socket_.is_open())
+ {
+ std::cout << "Connect timed out\n";
+
+ // Try the next available endpoint.
+ start_connect(++endpoint_iter);
+ }
+
+ // Check if the connect operation failed before the deadline expired.
+ else if (ec)
+ {
+ std::cout << "Connect error: " << ec.message() << "\n";
+
+ // We need to close the socket used in the previous connection attempt
+ // before starting a new one.
+ socket_.close();
+
+ // Try the next available endpoint.
+ start_connect(++endpoint_iter);
+ }
+
+ // Otherwise we have successfully established a connection.
+ else
+ {
+ std::cout << "Connected to " << endpoint_iter->endpoint() << "\n";
+
+ // Start the input actor.
+ start_read();
+
+ // Start the heartbeat actor.
+ start_write();
+ }
+ }
+
+ void start_read()
+ {
+ // Set a deadline for the read operation.
+ deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+ // Start an asynchronous operation to read a newline-delimited message.
+ asio::async_read_until(socket_, input_buffer_, '\n',
+ boost::bind(&client::handle_read, this, _1));
+ }
+
+ void handle_read(const asio::error_code& ec)
+ {
+ if (stopped_)
+ return;
+
+ if (!ec)
+ {
+ // Extract the newline-delimited message from the buffer.
+ std::string line;
+ std::istream is(&input_buffer_);
+ std::getline(is, line);
+
+ // Empty messages are heartbeats and so ignored.
+ if (!line.empty())
+ {
+ std::cout << "Received: " << line << "\n";
+ }
+
+ start_read();
+ }
+ else
+ {
+ std::cout << "Error on receive: " << ec.message() << "\n";
+
+ stop();
+ }
+ }
+
+ void start_write()
+ {
+ if (stopped_)
+ return;
+
+ // Start an asynchronous operation to send a heartbeat message.
+ asio::async_write(socket_, asio::buffer("\n", 1),
+ boost::bind(&client::handle_write, this, _1));
+ }
+
+ void handle_write(const asio::error_code& ec)
+ {
+ if (stopped_)
+ return;
+
+ if (!ec)
+ {
+ // Wait 10 seconds before sending the next heartbeat.
+ heartbeat_timer_.expires_from_now(boost::posix_time::seconds(10));
+ heartbeat_timer_.async_wait(boost::bind(&client::start_write, this));
+ }
+ else
+ {
+ std::cout << "Error on heartbeat: " << ec.message() << "\n";
+
+ stop();
+ }
+ }
+
+ void check_deadline()
+ {
+ if (stopped_)
+ return;
+
+ // Check whether the deadline has passed. We compare the deadline against
+ // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run.
+ if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+ {
+ // The deadline has passed. The socket is closed so that any outstanding
+ // asynchronous operations are cancelled.
+ socket_.close();
+
+ // There is no longer an active deadline. The expiry is set to positive
+ // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+ }
+
+ // Put the actor back to sleep.
+ deadline_.async_wait(boost::bind(&client::check_deadline, this));
+ }
+
+private:
+ bool stopped_;
+ tcp::resolver::results_type endpoints_;
+ tcp::socket socket_;
+ asio::streambuf input_buffer_;
+ deadline_timer deadline_;
+ deadline_timer heartbeat_timer_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+ tcp::resolver r(io_context);
+ client c(io_context);
+
+ c.start(r.resolve(argv[1], argv[2]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp b/3rdparty/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp
new file mode 100644
index 00000000000..69d467af1bb
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp
@@ -0,0 +1,242 @@
+//
+// blocking_tcp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio/connect.hpp"
+#include "asio/deadline_timer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/read_until.hpp"
+#include "asio/streambuf.hpp"
+#include "asio/system_error.hpp"
+#include "asio/write.hpp"
+#include "asio/thread.hpp"
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+using asio::deadline_timer;
+using asio::ip::tcp;
+using boost::lambda::bind;
+using boost::lambda::var;
+using boost::lambda::_1;
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Each asynchronous operation is given a deadline by which it must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+// +----------------+
+// | |
+// | check_deadline |<---+
+// | | |
+// +----------------+ | async_wait()
+// | |
+// +---------+
+//
+// If the actor determines that the deadline has expired, the socket is closed
+// and any outstanding operations are consequently cancelled. The socket
+// operations themselves use boost::lambda function objects as completion
+// handlers. For a given socket operation, the client object runs the
+// io_context to block thread execution until the actor completes.
+//
+class client
+{
+public:
+ client()
+ : socket_(io_context_),
+ deadline_(io_context_)
+ {
+ // No deadline is required until the first socket operation is started. We
+ // set the deadline to positive infinity so that the actor takes no action
+ // until a specific deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+
+ // Start the persistent actor that checks for deadline expiry.
+ check_deadline();
+ }
+
+ void connect(const std::string& host, const std::string& service,
+ boost::posix_time::time_duration timeout)
+ {
+ // Resolve the host name and service to a list of endpoints.
+ tcp::resolver::results_type endpoints =
+ tcp::resolver(io_context_).resolve(host, service);
+
+ // Set a deadline for the asynchronous operation. As a host name may
+ // resolve to multiple endpoints, this function uses the composed operation
+ // async_connect. The deadline applies to the entire operation, rather than
+ // individual connection attempts.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ asio::error_code ec = asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ asio::async_connect(socket_, endpoints, var(ec) = _1);
+
+ // Block until the asynchronous operation has completed.
+ do io_context_.run_one(); while (ec == asio::error::would_block);
+
+ // Determine whether a connection was successfully established. The
+ // deadline actor may have had a chance to run and close our socket, even
+ // though the connect operation notionally succeeded. Therefore we must
+ // check whether the socket is still open before deciding if we succeeded
+ // or failed.
+ if (ec || !socket_.is_open())
+ throw asio::system_error(
+ ec ? ec : asio::error::operation_aborted);
+ }
+
+ std::string read_line(boost::posix_time::time_duration timeout)
+ {
+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_read_until), the deadline applies to the
+ // entire operation, rather than individual reads from the socket.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ asio::error_code ec = asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ asio::async_read_until(socket_, input_buffer_, '\n', var(ec) = _1);
+
+ // Block until the asynchronous operation has completed.
+ do io_context_.run_one(); while (ec == asio::error::would_block);
+
+ if (ec)
+ throw asio::system_error(ec);
+
+ std::string line;
+ std::istream is(&input_buffer_);
+ std::getline(is, line);
+ return line;
+ }
+
+ void write_line(const std::string& line,
+ boost::posix_time::time_duration timeout)
+ {
+ std::string data = line + "\n";
+
+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_write), the deadline applies to the entire
+ // operation, rather than individual writes to the socket.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variable that receives the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ asio::error_code ec = asio::error::would_block;
+
+ // Start the asynchronous operation itself. The boost::lambda function
+ // object is used as a callback and will update the ec variable when the
+ // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.
+ asio::async_write(socket_, asio::buffer(data), var(ec) = _1);
+
+ // Block until the asynchronous operation has completed.
+ do io_context_.run_one(); while (ec == asio::error::would_block);
+
+ if (ec)
+ throw asio::system_error(ec);
+ }
+
+private:
+ void check_deadline()
+ {
+ // Check whether the deadline has passed. We compare the deadline against
+ // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run.
+ if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+ {
+ // The deadline has passed. The socket is closed so that any outstanding
+ // asynchronous operations are cancelled. This allows the blocked
+ // connect(), read_line() or write_line() functions to return.
+ asio::error_code ignored_ec;
+ socket_.close(ignored_ec);
+
+ // There is no longer an active deadline. The expiry is set to positive
+ // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+ }
+
+ // Put the actor back to sleep.
+ deadline_.async_wait(bind(&client::check_deadline, this));
+ }
+
+ asio::io_context io_context_;
+ tcp::socket socket_;
+ deadline_timer deadline_;
+ asio::streambuf input_buffer_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 4)
+ {
+ std::cerr << "Usage: blocking_tcp <host> <port> <message>\n";
+ return 1;
+ }
+
+ client c;
+ c.connect(argv[1], argv[2], boost::posix_time::seconds(10));
+
+ boost::posix_time::ptime time_sent =
+ boost::posix_time::microsec_clock::universal_time();
+
+ c.write_line(argv[3], boost::posix_time::seconds(10));
+
+ for (;;)
+ {
+ std::string line = c.read_line(boost::posix_time::seconds(10));
+
+ // Keep going until we get back the line that was sent.
+ if (line == argv[3])
+ break;
+ }
+
+ boost::posix_time::ptime time_received =
+ boost::posix_time::microsec_clock::universal_time();
+
+ std::cout << "Round trip time: ";
+ std::cout << (time_received - time_sent).total_microseconds();
+ std::cout << " microseconds\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp b/3rdparty/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp
new file mode 100644
index 00000000000..fd2da7640b8
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp
@@ -0,0 +1,182 @@
+//
+// blocking_udp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio/deadline_timer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/udp.hpp"
+#include <cstdlib>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <iostream>
+
+using asio::deadline_timer;
+using asio::ip::udp;
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Each asynchronous operation is given a deadline by which it must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+// +----------------+
+// | |
+// | check_deadline |<---+
+// | | |
+// +----------------+ | async_wait()
+// | |
+// +---------+
+//
+// If the actor determines that the deadline has expired, any outstanding
+// socket operations are cancelled. The socket operations themselves are
+// implemented as transient actors:
+//
+// +---------------+
+// | |
+// | receive |
+// | |
+// +---------------+
+// |
+// async_- | +----------------+
+// receive() | | |
+// +--->| handle_receive |
+// | |
+// +----------------+
+//
+// The client object runs the io_context to block thread execution until the
+// actor completes.
+//
+class client
+{
+public:
+ client(const udp::endpoint& listen_endpoint)
+ : socket_(io_context_, listen_endpoint),
+ deadline_(io_context_)
+ {
+ // No deadline is required until the first socket operation is started. We
+ // set the deadline to positive infinity so that the actor takes no action
+ // until a specific deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+
+ // Start the persistent actor that checks for deadline expiry.
+ check_deadline();
+ }
+
+ std::size_t receive(const asio::mutable_buffer& buffer,
+ boost::posix_time::time_duration timeout, asio::error_code& ec)
+ {
+ // Set a deadline for the asynchronous operation.
+ deadline_.expires_from_now(timeout);
+
+ // Set up the variables that receive the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ ec = asio::error::would_block;
+ std::size_t length = 0;
+
+ // Start the asynchronous operation itself. The handle_receive function
+ // used as a callback will update the ec and length variables.
+ socket_.async_receive(asio::buffer(buffer),
+ boost::bind(&client::handle_receive, _1, _2, &ec, &length));
+
+ // Block until the asynchronous operation has completed.
+ do io_context_.run_one(); while (ec == asio::error::would_block);
+
+ return length;
+ }
+
+private:
+ void check_deadline()
+ {
+ // Check whether the deadline has passed. We compare the deadline against
+ // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run.
+ if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+ {
+ // The deadline has passed. The outstanding asynchronous operation needs
+ // to be cancelled so that the blocked receive() function will return.
+ //
+ // Please note that cancel() has portability issues on some versions of
+ // Microsoft Windows, and it may be necessary to use close() instead.
+ // Consult the documentation for cancel() for further information.
+ socket_.cancel();
+
+ // There is no longer an active deadline. The expiry is set to positive
+ // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin);
+ }
+
+ // Put the actor back to sleep.
+ deadline_.async_wait(boost::bind(&client::check_deadline, this));
+ }
+
+ static void handle_receive(
+ const asio::error_code& ec, std::size_t length,
+ asio::error_code* out_ec, std::size_t* out_length)
+ {
+ *out_ec = ec;
+ *out_length = length;
+ }
+
+private:
+ asio::io_context io_context_;
+ udp::socket socket_;
+ deadline_timer deadline_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ using namespace std; // For atoi.
+
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_udp_timeout <listen_addr> <listen_port>\n";
+ return 1;
+ }
+
+ udp::endpoint listen_endpoint(
+ asio::ip::make_address(argv[1]),
+ std::atoi(argv[2]));
+
+ client c(listen_endpoint);
+
+ for (;;)
+ {
+ char data[1024];
+ asio::error_code ec;
+ std::size_t n = c.receive(asio::buffer(data),
+ boost::posix_time::seconds(10), ec);
+
+ if (ec)
+ {
+ std::cout << "Receive error: " << ec.message() << "\n";
+ }
+ else
+ {
+ std::cout << "Received: ";
+ std::cout.write(data, n);
+ std::cout << "\n";
+ }
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/timeouts/server.cpp b/3rdparty/asio/src/examples/cpp03/timeouts/server.cpp
new file mode 100644
index 00000000000..212cd90d820
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timeouts/server.cpp
@@ -0,0 +1,427 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <algorithm>
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <set>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "asio/deadline_timer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/ip/udp.hpp"
+#include "asio/read_until.hpp"
+#include "asio/streambuf.hpp"
+#include "asio/write.hpp"
+
+using asio::deadline_timer;
+using asio::ip::tcp;
+using asio::ip::udp;
+
+//----------------------------------------------------------------------
+
+class subscriber
+{
+public:
+ virtual ~subscriber() {}
+ virtual void deliver(const std::string& msg) = 0;
+};
+
+typedef boost::shared_ptr<subscriber> subscriber_ptr;
+
+//----------------------------------------------------------------------
+
+class channel
+{
+public:
+ void join(subscriber_ptr subscriber)
+ {
+ subscribers_.insert(subscriber);
+ }
+
+ void leave(subscriber_ptr subscriber)
+ {
+ subscribers_.erase(subscriber);
+ }
+
+ void deliver(const std::string& msg)
+ {
+ std::for_each(subscribers_.begin(), subscribers_.end(),
+ boost::bind(&subscriber::deliver, _1, boost::ref(msg)));
+ }
+
+private:
+ std::set<subscriber_ptr> subscribers_;
+};
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Some asynchronous operations are given deadlines by which they must complete.
+// Deadlines are enforced by two "actors" that persist for the lifetime of the
+// session object, one for input and one for output:
+//
+// +----------------+ +----------------+
+// | | | |
+// | check_deadline |<---+ | check_deadline |<---+
+// | | | async_wait() | | | async_wait()
+// +----------------+ | on input +----------------+ | on output
+// | | deadline | | deadline
+// +---------+ +---------+
+//
+// If either deadline actor determines that the corresponding deadline has
+// expired, the socket is closed and any outstanding operations are cancelled.
+//
+// The input actor reads messages from the socket, where messages are delimited
+// by the newline character:
+//
+// +------------+
+// | |
+// | start_read |<---+
+// | | |
+// +------------+ |
+// | |
+// async_- | +-------------+
+// read_- | | |
+// until() +--->| handle_read |
+// | |
+// +-------------+
+//
+// The deadline for receiving a complete message is 30 seconds. If a non-empty
+// message is received, it is delivered to all subscribers. If a heartbeat (a
+// message that consists of a single newline character) is received, a heartbeat
+// is enqueued for the client, provided there are no other messages waiting to
+// be sent.
+//
+// The output actor is responsible for sending messages to the client:
+//
+// +--------------+
+// | |<---------------------+
+// | await_output | |
+// | |<---+ |
+// +--------------+ | |
+// | | | async_wait() |
+// | +--------+ |
+// V |
+// +-------------+ +--------------+
+// | | async_write() | |
+// | start_write |-------------->| handle_write |
+// | | | |
+// +-------------+ +--------------+
+//
+// The output actor first waits for an output message to be enqueued. It does
+// this by using a deadline_timer as an asynchronous condition variable. The
+// deadline_timer will be signalled whenever the output queue is non-empty.
+//
+// Once a message is available, it is sent to the client. The deadline for
+// sending a complete message is 30 seconds. After the message is successfully
+// sent, the output actor again waits for the output queue to become non-empty.
+//
+class tcp_session
+ : public subscriber,
+ public boost::enable_shared_from_this<tcp_session>
+{
+public:
+ tcp_session(asio::io_context& io_context, channel& ch)
+ : channel_(ch),
+ socket_(io_context),
+ input_deadline_(io_context),
+ non_empty_output_queue_(io_context),
+ output_deadline_(io_context)
+ {
+ input_deadline_.expires_at(boost::posix_time::pos_infin);
+ output_deadline_.expires_at(boost::posix_time::pos_infin);
+
+ // The non_empty_output_queue_ deadline_timer is set to pos_infin whenever
+ // the output queue is empty. This ensures that the output actor stays
+ // asleep until a message is put into the queue.
+ non_empty_output_queue_.expires_at(boost::posix_time::pos_infin);
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ // Called by the server object to initiate the four actors.
+ void start()
+ {
+ channel_.join(shared_from_this());
+
+ start_read();
+
+ input_deadline_.async_wait(
+ boost::bind(&tcp_session::check_deadline,
+ shared_from_this(), &input_deadline_));
+
+ await_output();
+
+ output_deadline_.async_wait(
+ boost::bind(&tcp_session::check_deadline,
+ shared_from_this(), &output_deadline_));
+ }
+
+private:
+ void stop()
+ {
+ channel_.leave(shared_from_this());
+
+ asio::error_code ignored_ec;
+ socket_.close(ignored_ec);
+ input_deadline_.cancel();
+ non_empty_output_queue_.cancel();
+ output_deadline_.cancel();
+ }
+
+ bool stopped() const
+ {
+ return !socket_.is_open();
+ }
+
+ void deliver(const std::string& msg)
+ {
+ output_queue_.push_back(msg + "\n");
+
+ // Signal that the output queue contains messages. Modifying the expiry
+ // will wake the output actor, if it is waiting on the timer.
+ non_empty_output_queue_.expires_at(boost::posix_time::neg_infin);
+ }
+
+ void start_read()
+ {
+ // Set a deadline for the read operation.
+ input_deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+ // Start an asynchronous operation to read a newline-delimited message.
+ asio::async_read_until(socket_, input_buffer_, '\n',
+ boost::bind(&tcp_session::handle_read, shared_from_this(), _1));
+ }
+
+ void handle_read(const asio::error_code& ec)
+ {
+ if (stopped())
+ return;
+
+ if (!ec)
+ {
+ // Extract the newline-delimited message from the buffer.
+ std::string msg;
+ std::istream is(&input_buffer_);
+ std::getline(is, msg);
+
+ if (!msg.empty())
+ {
+ channel_.deliver(msg);
+ }
+ else
+ {
+ // We received a heartbeat message from the client. If there's nothing
+ // else being sent or ready to be sent, send a heartbeat right back.
+ if (output_queue_.empty())
+ {
+ output_queue_.push_back("\n");
+
+ // Signal that the output queue contains messages. Modifying the
+ // expiry will wake the output actor, if it is waiting on the timer.
+ non_empty_output_queue_.expires_at(boost::posix_time::neg_infin);
+ }
+ }
+
+ start_read();
+ }
+ else
+ {
+ stop();
+ }
+ }
+
+ void await_output()
+ {
+ if (stopped())
+ return;
+
+ if (output_queue_.empty())
+ {
+ // There are no messages that are ready to be sent. The actor goes to
+ // sleep by waiting on the non_empty_output_queue_ timer. When a new
+ // message is added, the timer will be modified and the actor will wake.
+ non_empty_output_queue_.expires_at(boost::posix_time::pos_infin);
+ non_empty_output_queue_.async_wait(
+ boost::bind(&tcp_session::await_output, shared_from_this()));
+ }
+ else
+ {
+ start_write();
+ }
+ }
+
+ void start_write()
+ {
+ // Set a deadline for the write operation.
+ output_deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+ // Start an asynchronous operation to send a message.
+ asio::async_write(socket_,
+ asio::buffer(output_queue_.front()),
+ boost::bind(&tcp_session::handle_write, shared_from_this(), _1));
+ }
+
+ void handle_write(const asio::error_code& ec)
+ {
+ if (stopped())
+ return;
+
+ if (!ec)
+ {
+ output_queue_.pop_front();
+
+ await_output();
+ }
+ else
+ {
+ stop();
+ }
+ }
+
+ void check_deadline(deadline_timer* deadline)
+ {
+ if (stopped())
+ return;
+
+ // Check whether the deadline has passed. We compare the deadline against
+ // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run.
+ if (deadline->expires_at() <= deadline_timer::traits_type::now())
+ {
+ // The deadline has passed. Stop the session. The other actors will
+ // terminate as soon as possible.
+ stop();
+ }
+ else
+ {
+ // Put the actor back to sleep.
+ deadline->async_wait(
+ boost::bind(&tcp_session::check_deadline,
+ shared_from_this(), deadline));
+ }
+ }
+
+ channel& channel_;
+ tcp::socket socket_;
+ asio::streambuf input_buffer_;
+ deadline_timer input_deadline_;
+ std::deque<std::string> output_queue_;
+ deadline_timer non_empty_output_queue_;
+ deadline_timer output_deadline_;
+};
+
+typedef boost::shared_ptr<tcp_session> tcp_session_ptr;
+
+//----------------------------------------------------------------------
+
+class udp_broadcaster
+ : public subscriber
+{
+public:
+ udp_broadcaster(asio::io_context& io_context,
+ const udp::endpoint& broadcast_endpoint)
+ : socket_(io_context)
+ {
+ socket_.connect(broadcast_endpoint);
+ }
+
+private:
+ void deliver(const std::string& msg)
+ {
+ asio::error_code ignored_ec;
+ socket_.send(asio::buffer(msg), 0, ignored_ec);
+ }
+
+ udp::socket socket_;
+};
+
+//----------------------------------------------------------------------
+
+class server
+{
+public:
+ server(asio::io_context& io_context,
+ const tcp::endpoint& listen_endpoint,
+ const udp::endpoint& broadcast_endpoint)
+ : io_context_(io_context),
+ acceptor_(io_context, listen_endpoint)
+ {
+ subscriber_ptr bc(new udp_broadcaster(io_context_, broadcast_endpoint));
+ channel_.join(bc);
+
+ start_accept();
+ }
+
+ void start_accept()
+ {
+ tcp_session_ptr new_session(new tcp_session(io_context_, channel_));
+
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session, _1));
+ }
+
+ void handle_accept(tcp_session_ptr session,
+ const asio::error_code& ec)
+ {
+ if (!ec)
+ {
+ session->start();
+ }
+
+ start_accept();
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::acceptor acceptor_;
+ channel channel_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ using namespace std; // For atoi.
+
+ if (argc != 4)
+ {
+ std::cerr << "Usage: server <listen_port> <bcast_address> <bcast_port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::endpoint listen_endpoint(tcp::v4(), atoi(argv[1]));
+
+ udp::endpoint broadcast_endpoint(
+ asio::ip::make_address(argv[2]), atoi(argv[3]));
+
+ server s(io_context, listen_endpoint, broadcast_endpoint);
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/timers/.gitignore b/3rdparty/asio/src/examples/cpp03/timers/.gitignore
new file mode 100644
index 00000000000..a3fe695226f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timers/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*timer
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/timers/tick_count_timer.cpp b/3rdparty/asio/src/examples/cpp03/timers/tick_count_timer.cpp
new file mode 100644
index 00000000000..8b98cfd2a54
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timers/tick_count_timer.cpp
@@ -0,0 +1,123 @@
+//
+// tick_count_timer.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <ctime>
+#include <iostream>
+
+#if defined(WIN32)
+# include <windows.h>
+#else
+# error This example is for Windows only!
+#endif
+
+struct tick_count_traits
+{
+ // The time type. This type has no constructor that takes a DWORD to ensure
+ // that the timer can only be used with relative times.
+ class time_type
+ {
+ public:
+ time_type() : ticks_(0) {}
+ private:
+ friend struct tick_count_traits;
+ DWORD ticks_;
+ };
+
+ // The duration type. According to the TimeTraits requirements, the duration
+ // must be a signed type. This means we can't handle durations larger than
+ // 2^31.
+ class duration_type
+ {
+ public:
+ duration_type() : ticks_(0) {}
+ duration_type(LONG ticks) : ticks_(ticks) {}
+ private:
+ friend struct tick_count_traits;
+ LONG ticks_;
+ };
+
+ // Get the current time.
+ static time_type now()
+ {
+ time_type result;
+ result.ticks_ = ::GetTickCount();
+ return result;
+ }
+
+ // Add a duration to a time.
+ static time_type add(const time_type& t, const duration_type& d)
+ {
+ time_type result;
+ result.ticks_ = t.ticks_ + d.ticks_;
+ return result;
+ }
+
+ // Subtract one time from another.
+ static duration_type subtract(const time_type& t1, const time_type& t2)
+ {
+ // DWORD tick count values can wrap (see less_than() below). We'll convert
+ // to a duration by taking the absolute difference and adding the sign
+ // based on which is the "lesser" absolute time.
+ return duration_type(less_than(t1, t2)
+ ? -static_cast<LONG>(t2.ticks_ - t1.ticks_)
+ : static_cast<LONG>(t1.ticks_ - t2.ticks_));
+ }
+
+ // Test whether one time is less than another.
+ static bool less_than(const time_type& t1, const time_type& t2)
+ {
+ // DWORD tick count values wrap periodically, so we'll use a heuristic that
+ // says that if subtracting t1 from t2 yields a value smaller than 2^31,
+ // then t1 is probably less than t2. This means that we can't handle
+ // durations larger than 2^31, which shouldn't be a problem in practice.
+ return (t2.ticks_ - t1.ticks_) < static_cast<DWORD>(1 << 31);
+ }
+
+ // Convert to POSIX duration type.
+ static boost::posix_time::time_duration to_posix_duration(
+ const duration_type& d)
+ {
+ return boost::posix_time::milliseconds(d.ticks_);
+ }
+};
+
+typedef asio::basic_deadline_timer<
+ DWORD, tick_count_traits> tick_count_timer;
+
+void handle_timeout(const asio::error_code&)
+{
+ std::cout << "handle_timeout\n";
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ tick_count_timer timer(io_context, 5000);
+ std::cout << "Starting synchronous wait\n";
+ timer.wait();
+ std::cout << "Finished synchronous wait\n";
+
+ timer.expires_from_now(5000);
+ std::cout << "Starting asynchronous wait\n";
+ timer.async_wait(&handle_timeout);
+ io_context.run();
+ std::cout << "Finished asynchronous wait\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/timers/time_t_timer.cpp b/3rdparty/asio/src/examples/cpp03/timers/time_t_timer.cpp
new file mode 100644
index 00000000000..8a434e9b20c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/timers/time_t_timer.cpp
@@ -0,0 +1,93 @@
+//
+// time_t_timer.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <ctime>
+#include <iostream>
+
+struct time_t_traits
+{
+ // The time type.
+ typedef std::time_t time_type;
+
+ // The duration type.
+ struct duration_type
+ {
+ duration_type() : value(0) {}
+ duration_type(std::time_t v) : value(v) {}
+ std::time_t value;
+ };
+
+ // Get the current time.
+ static time_type now()
+ {
+ return std::time(0);
+ }
+
+ // Add a duration to a time.
+ static time_type add(const time_type& t, const duration_type& d)
+ {
+ return t + d.value;
+ }
+
+ // Subtract one time from another.
+ static duration_type subtract(const time_type& t1, const time_type& t2)
+ {
+ return duration_type(t1 - t2);
+ }
+
+ // Test whether one time is less than another.
+ static bool less_than(const time_type& t1, const time_type& t2)
+ {
+ return t1 < t2;
+ }
+
+ // Convert to POSIX duration type.
+ static boost::posix_time::time_duration to_posix_duration(
+ const duration_type& d)
+ {
+ return boost::posix_time::seconds(d.value);
+ }
+};
+
+typedef asio::basic_deadline_timer<
+ std::time_t, time_t_traits> time_t_timer;
+
+void handle_timeout(const asio::error_code&)
+{
+ std::cout << "handle_timeout\n";
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ time_t_timer timer(io_context);
+
+ timer.expires_from_now(5);
+ std::cout << "Starting synchronous wait\n";
+ timer.wait();
+ std::cout << "Finished synchronous wait\n";
+
+ timer.expires_from_now(5);
+ std::cout << "Starting asynchronous wait\n";
+ timer.async_wait(&handle_timeout);
+ io_context.run();
+ std::cout << "Finished asynchronous wait\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/.gitignore
new file mode 100644
index 00000000000..2926eaf9bf6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/.gitignore
@@ -0,0 +1,10 @@
+client
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/client.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/client.cpp
new file mode 100644
index 00000000000..9784d48a6fb
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime1/client.cpp
@@ -0,0 +1,57 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <boost/array.hpp>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: client <host>" << std::endl;
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::resolver resolver(io_context);
+ tcp::resolver::results_type endpoints =
+ resolver.resolve(argv[1], "daytime");
+
+ tcp::socket socket(io_context);
+ asio::connect(socket, endpoints);
+
+ for (;;)
+ {
+ boost::array<char, 128> buf;
+ asio::error_code error;
+
+ size_t len = socket.read_some(asio::buffer(buf), error);
+
+ if (error == asio::error::eof)
+ break; // Connection closed cleanly by peer.
+ else if (error)
+ throw asio::system_error(error); // Some other error.
+
+ std::cout.write(buf.data(), len);
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/.gitignore
new file mode 100644
index 00000000000..7f06efb3296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/.gitignore
@@ -0,0 +1,10 @@
+server
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/server.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/server.cpp
new file mode 100644
index 00000000000..f662ed246c4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime2/server.cpp
@@ -0,0 +1,50 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));
+
+ for (;;)
+ {
+ tcp::socket socket(io_context);
+ acceptor.accept(socket);
+
+ std::string message = make_daytime_string();
+
+ asio::error_code ignored_error;
+ asio::write(socket, asio::buffer(message), ignored_error);
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/.gitignore
new file mode 100644
index 00000000000..7f06efb3296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/.gitignore
@@ -0,0 +1,10 @@
+server
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/server.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/server.cpp
new file mode 100644
index 00000000000..cb2c9480594
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime3/server.cpp
@@ -0,0 +1,117 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+class tcp_connection
+ : public boost::enable_shared_from_this<tcp_connection>
+{
+public:
+ typedef boost::shared_ptr<tcp_connection> pointer;
+
+ static pointer create(asio::io_context& io_context)
+ {
+ return pointer(new tcp_connection(io_context));
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ message_ = make_daytime_string();
+
+ asio::async_write(socket_, asio::buffer(message_),
+ boost::bind(&tcp_connection::handle_write, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+private:
+ tcp_connection(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ void handle_write(const asio::error_code& /*error*/,
+ size_t /*bytes_transferred*/)
+ {
+ }
+
+ tcp::socket socket_;
+ std::string message_;
+};
+
+class tcp_server
+{
+public:
+ tcp_server(asio::io_context& io_context)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ {
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ tcp_connection::pointer new_connection =
+ tcp_connection::create(acceptor_.get_executor().context());
+
+ acceptor_.async_accept(new_connection->socket(),
+ boost::bind(&tcp_server::handle_accept, this, new_connection,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(tcp_connection::pointer new_connection,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_connection->start();
+ }
+
+ start_accept();
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+ tcp_server server(io_context);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/.gitignore
new file mode 100644
index 00000000000..2926eaf9bf6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/.gitignore
@@ -0,0 +1,10 @@
+client
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/client.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/client.cpp
new file mode 100644
index 00000000000..da3b651d56d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime4/client.cpp
@@ -0,0 +1,52 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <boost/array.hpp>
+#include <asio.hpp>
+
+using asio::ip::udp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: client <host>" << std::endl;
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ udp::resolver resolver(io_context);
+ udp::endpoint receiver_endpoint =
+ *resolver.resolve(udp::v4(), argv[1], "daytime").begin();
+
+ udp::socket socket(io_context);
+ socket.open(udp::v4());
+
+ boost::array<char, 1> send_buf = {{ 0 }};
+ socket.send_to(asio::buffer(send_buf), receiver_endpoint);
+
+ boost::array<char, 128> recv_buf;
+ udp::endpoint sender_endpoint;
+ size_t len = socket.receive_from(
+ asio::buffer(recv_buf), sender_endpoint);
+
+ std::cout.write(recv_buf.data(), len);
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/.gitignore
new file mode 100644
index 00000000000..7f06efb3296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/.gitignore
@@ -0,0 +1,10 @@
+server
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/server.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/server.cpp
new file mode 100644
index 00000000000..fdf452562d2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime5/server.cpp
@@ -0,0 +1,58 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <boost/array.hpp>
+#include <asio.hpp>
+
+using asio::ip::udp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+
+ udp::socket socket(io_context, udp::endpoint(udp::v4(), 13));
+
+ for (;;)
+ {
+ boost::array<char, 1> recv_buf;
+ udp::endpoint remote_endpoint;
+ asio::error_code error;
+ socket.receive_from(asio::buffer(recv_buf),
+ remote_endpoint, 0, error);
+
+ if (error && error != asio::error::message_size)
+ throw asio::system_error(error);
+
+ std::string message = make_daytime_string();
+
+ asio::error_code ignored_error;
+ socket.send_to(asio::buffer(message),
+ remote_endpoint, 0, ignored_error);
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/.gitignore
new file mode 100644
index 00000000000..7f06efb3296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/.gitignore
@@ -0,0 +1,10 @@
+server
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/server.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/server.cpp
new file mode 100644
index 00000000000..d67045ff990
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime6/server.cpp
@@ -0,0 +1,89 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <asio.hpp>
+
+using asio::ip::udp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+class udp_server
+{
+public:
+ udp_server(asio::io_context& io_context)
+ : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ {
+ start_receive();
+ }
+
+private:
+ void start_receive()
+ {
+ socket_.async_receive_from(
+ asio::buffer(recv_buffer_), remote_endpoint_,
+ boost::bind(&udp_server::handle_receive, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+
+ void handle_receive(const asio::error_code& error,
+ std::size_t /*bytes_transferred*/)
+ {
+ if (!error || error == asio::error::message_size)
+ {
+ boost::shared_ptr<std::string> message(
+ new std::string(make_daytime_string()));
+
+ socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ boost::bind(&udp_server::handle_send, this, message,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+
+ start_receive();
+ }
+ }
+
+ void handle_send(boost::shared_ptr<std::string> /*message*/,
+ const asio::error_code& /*error*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ }
+
+ udp::socket socket_;
+ udp::endpoint remote_endpoint_;
+ boost::array<char, 1> recv_buffer_;
+};
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+ udp_server server(io_context);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/.gitignore
new file mode 100644
index 00000000000..7f06efb3296
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/.gitignore
@@ -0,0 +1,10 @@
+server
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/server.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/server.cpp
new file mode 100644
index 00000000000..b9dc60558c9
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime7/server.cpp
@@ -0,0 +1,158 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <asio.hpp>
+
+using asio::ip::tcp;
+using asio::ip::udp;
+
+std::string make_daytime_string()
+{
+ using namespace std; // For time_t, time and ctime;
+ time_t now = time(0);
+ return ctime(&now);
+}
+
+class tcp_connection
+ : public boost::enable_shared_from_this<tcp_connection>
+{
+public:
+ typedef boost::shared_ptr<tcp_connection> pointer;
+
+ static pointer create(asio::io_context& io_context)
+ {
+ return pointer(new tcp_connection(io_context));
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ message_ = make_daytime_string();
+
+ asio::async_write(socket_, asio::buffer(message_),
+ boost::bind(&tcp_connection::handle_write, shared_from_this()));
+ }
+
+private:
+ tcp_connection(asio::io_context& io_context)
+ : socket_(io_context)
+ {
+ }
+
+ void handle_write()
+ {
+ }
+
+ tcp::socket socket_;
+ std::string message_;
+};
+
+class tcp_server
+{
+public:
+ tcp_server(asio::io_context& io_context)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
+ {
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ tcp_connection::pointer new_connection =
+ tcp_connection::create(acceptor_.get_executor().context());
+
+ acceptor_.async_accept(new_connection->socket(),
+ boost::bind(&tcp_server::handle_accept, this, new_connection,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(tcp_connection::pointer new_connection,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_connection->start();
+ }
+
+ start_accept();
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+class udp_server
+{
+public:
+ udp_server(asio::io_context& io_context)
+ : socket_(io_context, udp::endpoint(udp::v4(), 13))
+ {
+ start_receive();
+ }
+
+private:
+ void start_receive()
+ {
+ socket_.async_receive_from(
+ asio::buffer(recv_buffer_), remote_endpoint_,
+ boost::bind(&udp_server::handle_receive, this,
+ asio::placeholders::error));
+ }
+
+ void handle_receive(const asio::error_code& error)
+ {
+ if (!error || error == asio::error::message_size)
+ {
+ boost::shared_ptr<std::string> message(
+ new std::string(make_daytime_string()));
+
+ socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
+ boost::bind(&udp_server::handle_send, this, message));
+
+ start_receive();
+ }
+ }
+
+ void handle_send(boost::shared_ptr<std::string> /*message*/)
+ {
+ }
+
+ udp::socket socket_;
+ udp::endpoint remote_endpoint_;
+ boost::array<char, 1> recv_buffer_;
+};
+
+int main()
+{
+ try
+ {
+ asio::io_context io_context;
+ tcp_server server1(io_context);
+ udp_server server2(io_context);
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/daytime_dox.txt b/3rdparty/asio/src/examples/cpp03/tutorial/daytime_dox.txt
new file mode 100644
index 00000000000..1bf591a43a8
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/daytime_dox.txt
@@ -0,0 +1,502 @@
+//
+// Copyright (c) 2003-2016 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)
+//
+
+/**
+\page tutdaytime1 Daytime.1 - A synchronous TCP daytime client
+
+This tutorial program shows how to use asio to implement a client application
+with TCP.
+
+\dontinclude daytime1/client.cpp
+\skip #include
+
+We start by including the necessary header files.
+
+\until asio.hpp
+
+The purpose of this application is to access a daytime service,
+so we need the user to specify the server.
+
+\until }
+
+All programs that use asio need to have at least one asio::io_service
+object.
+
+\until asio::io_service
+
+We need to turn the server name that was specified as a parameter to the
+application, into a TCP endpoint. To do this we use an
+asio::ip::tcp::resolver object.
+
+\until tcp::resolver
+
+A resolver takes a query object and turns it into a list of endpoints. We
+construct a query using the name of the server, specified in <tt>argv[1]</tt>,
+and the name of the service, in this case <tt>"daytime"</tt>.
+
+\until tcp::resolver::query
+
+The list of endpoints is returned using an iterator of type
+asio::ip::tcp::resolver::iterator. (Note that a default constructed
+asio::ip::tcp::resolver::iterator object can be used as an end iterator.)
+
+\until tcp::resolver::iterator
+
+Now we create and connect the socket. The list of endpoints obtained above may
+contain both IPv4 and IPv6 endpoints, so we need to try each of them until we
+find one that works. This keeps the client program independent of a specific IP
+version. The asio::connect() function does this for us automatically.
+
+\until asio::connect
+
+The connection is open. All we need to do now is read the response from the
+daytime service.
+
+We use a <tt>boost::array</tt> to hold the received data. The asio::buffer()
+function automatically determines the size of the array to help prevent buffer
+overruns. Instead of a <tt>boost::array</tt>, we could have used a <tt>char
+[]</tt> or <tt>std::vector</tt>.
+
+\until read_some
+
+When the server closes the connection, the asio::ip::tcp::socket::read_some()
+function will exit with the asio::error::eof error, which is how we know to
+exit the loop.
+
+\until }
+
+Finally, handle any exceptions that may have been thrown.
+
+\until }
+\until }
+
+See the \ref tutdaytime1src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Next: \ref tutdaytime2
+
+*/
+
+/**
+\page tutdaytime1src Source listing for Daytime.1
+\include daytime1/client.cpp
+Return to \ref tutdaytime1
+*/
+
+/**
+\page tutdaytime2 Daytime.2 - A synchronous TCP daytime server
+
+This tutorial program shows how to use asio to implement a server application
+with TCP.
+
+\dontinclude daytime2/server.cpp
+\skip #include
+
+\until using
+
+We define the function <tt>make_daytime_string()</tt> to create the string to
+be sent back to the client. This function will be reused in all of our daytime
+server applications.
+
+\until asio::io_service
+
+A asio::ip::tcp::acceptor object needs to be created to listen
+for new connections. It is initialised to listen on TCP port 13, for IP version 4.
+
+\until tcp::acceptor
+
+This is an iterative server, which means that it will handle one
+connection at a time. Create a socket that will represent the connection to the
+client, and then wait for a connection.
+
+\until acceptor.accept
+
+A client is accessing our service. Determine the current time
+and transfer this information to the client.
+
+\until }
+\until }
+
+Finally, handle any exceptions.
+
+\until }
+\until }
+
+See the \ref tutdaytime2src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime1 \n
+Next: \ref tutdaytime3
+
+*/
+
+/**
+\page tutdaytime2src Source listing for Daytime.2
+\include daytime2/server.cpp
+Return to \ref tutdaytime2
+*/
+
+/**
+\page tutdaytime3 Daytime.3 - An asynchronous TCP daytime server
+
+\section tutdaytime3funcmain The main() function
+
+\dontinclude daytime3/server.cpp
+\skip int main()
+\until try
+\until {
+
+We need to create a server object to accept incoming client connections. The
+asio::io_service object provides I/O services, such as sockets, that the
+server object will use.
+
+\until tcp_server
+
+Run the asio::io_service object so that it will perform asynchronous operations
+on your behalf.
+
+\until return 0;
+\until }
+
+\section tutdaytime3classtcp_server The tcp_server class
+
+\dontinclude daytime3/server.cpp
+\skip class tcp_server
+\until public:
+
+The constructor initialises an acceptor to listen on TCP port 13.
+
+\until private:
+
+The function <tt>start_accept()</tt> creates a socket and initiates an
+asynchronous accept operation to wait for a new connection.
+
+\until }
+
+The function <tt>handle_accept()</tt> is called when the asynchronous accept
+operation initiated by <tt>start_accept()</tt> finishes. It services the client
+request, and then calls <tt>start_accept()</tt> to initiate the next accept
+operation.
+
+\until }
+\until }
+
+\section tutdaytime3classtcp_connection The tcp_connection class
+
+We will use <tt>shared_ptr</tt> and <tt>enable_shared_from_this</tt> because we
+want to keep the <tt>tcp_connection</tt> object alive as long as there is an
+operation that refers to it.
+
+\dontinclude daytime3/server.cpp
+\skip class tcp_connection
+\until shared_ptr
+\until }
+\until }
+
+In the function <tt>start()</tt>, we call asio::async_write() to serve the data
+to the client. Note that we are using asio::async_write(), rather than
+asio::ip::tcp::socket::async_write_some(), to ensure that the entire block of
+data is sent.
+
+\until {
+
+The data to be sent is stored in the class member <tt>message_</tt> as we need
+to keep the data valid until the asynchronous operation is complete.
+
+\until message_
+
+When initiating the asynchronous operation, and if using \ref boost_bind, you
+must specify only the arguments that match the handler's parameter list. In
+this program, both of the argument placeholders (asio::placeholders::error and
+asio::placeholders::bytes_transferred) could potentially have been removed,
+since they are not being used in <tt>handle_write()</tt>.
+
+\until placeholders::bytes_transferred
+
+Any further actions for this client connection are now the responsibility of
+<tt>handle_write()</tt>.
+
+\until };
+
+\section tutdaytime3remunused Removing unused handler parameters
+
+You may have noticed that the <tt>error</tt>, and <tt>bytes_transferred</tt>
+parameters are not used in the body of the <tt>handle_write()</tt> function. If
+parameters are not needed, it is possible to remove them from the function so
+that it looks like:
+
+\code
+ void handle_write()
+ {
+ }
+\endcode
+
+The asio::async_write() call used to initiate the call can then be changed to
+just:
+
+\code
+ asio::async_write(socket_, asio::buffer(message_),
+ boost::bind(&tcp_connection::handle_write, shared_from_this()));
+\endcode
+
+See the \ref tutdaytime3src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime2 \n
+Next: \ref tutdaytime4
+
+*/
+
+/**
+\page tutdaytime3src Source listing for Daytime.3
+\include daytime3/server.cpp
+Return to \ref tutdaytime3
+*/
+
+/**
+\page tutdaytime4 Daytime.4 - A synchronous UDP daytime client
+
+This tutorial program shows how to use asio to implement a client application
+with UDP.
+
+\dontinclude daytime4/client.cpp
+\skip #include
+\until using asio::ip::udp;
+
+The start of the application is essentially the same as for the TCP daytime
+client.
+
+\until asio::io_service
+
+We use an asio::ip::udp::resolver object to find the correct remote endpoint to
+use based on the host and service names. The query is restricted to return only
+IPv4 endpoints by the asio::ip::udp::v4() argument.
+
+\until udp::v4
+
+The asio::ip::udp::resolver::resolve() function is guaranteed to return at
+least one endpoint in the list if it does not fail. This means it is safe to
+dereference the return value directly.
+
+\until udp::endpoint
+
+Since UDP is datagram-oriented, we will not be using a stream socket. Create an
+asio::ip::udp::socket and initiate contact with the remote endpoint.
+
+\until receiver_endpoint
+
+Now we need to be ready to accept whatever the server sends back to us. The
+endpoint on our side that receives the server's response will be initialised by
+asio::ip::udp::socket::receive_from().
+
+\until }
+
+Finally, handle any exceptions that may have been thrown.
+
+\until }
+\until }
+See the \ref tutdaytime4src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime3 \n
+Next: \ref tutdaytime5
+
+*/
+
+/**
+\page tutdaytime4src Source listing for Daytime.4
+\include daytime4/client.cpp
+Return to \ref tutdaytime4
+*/
+
+/**
+\page tutdaytime5 Daytime.5 - A synchronous UDP daytime server
+
+This tutorial program shows how to use asio to implement a server application
+with UDP.
+
+\dontinclude daytime5/server.cpp
+\skip int main()
+\until asio::io_service
+
+Create an asio::ip::udp::socket object to receive requests on UDP port 13.
+
+\until udp::socket
+
+Wait for a client to initiate contact with us. The remote_endpoint object will
+be populated by asio::ip::udp::socket::receive_from().
+
+\until throw
+
+Determine what we are going to send back to the client.
+
+\until std::string message
+
+Send the response to the remote_endpoint.
+
+\until }
+\until }
+
+Finally, handle any exceptions.
+
+\until }
+\until }
+
+See the \ref tutdaytime5src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime4 \n
+Next: \ref tutdaytime6
+
+*/
+
+/**
+\page tutdaytime5src Source listing for Daytime.5
+\include daytime5/server.cpp
+Return to \ref tutdaytime5
+*/
+
+/**
+\page tutdaytime6 Daytime.6 - An asynchronous UDP daytime server
+
+\section tutdaytime6funcmain The main() function
+
+\dontinclude daytime6/server.cpp
+\skip int main()
+\until try
+\until {
+
+Create a server object to accept incoming client requests, and run
+the asio::io_service object.
+
+\until return 0;
+\until }
+
+\section tutdaytime6classudp_server The udp_server class
+
+\dontinclude daytime6/server.cpp
+\skip class udp_server
+\until public:
+
+The constructor initialises a socket to listen on UDP port 13.
+
+\until private:
+\until {
+
+The function asio::ip::udp::socket::async_receive_from() will cause the
+application to listen in the background for a new request. When such a request
+is received, the asio::io_service object will invoke the
+<tt>handle_receive()</tt> function with two arguments: a value of type
+asio::error_code indicating whether the operation succeeded or failed, and a
+<tt>size_t</tt> value <tt>bytes_transferred</tt> specifying the number of bytes
+received.
+
+\until }
+
+The function <tt>handle_receive()</tt> will service the client request.
+
+\until {
+
+The <tt>error</tt> parameter contains the result of the asynchronous operation.
+Since we only provide the 1-byte <tt>recv_buffer_</tt> to contain the client's
+request, the asio::io_service object would return an error if the client sent
+anything larger. We can ignore such an error if it comes up.
+
+\until {
+
+Determine what we are going to send.
+
+\until make_daytime_string()
+
+We now call asio::ip::udp::socket::async_send_to() to serve the data to the
+client.
+
+\until asio::placeholders::bytes_transferred
+
+When initiating the asynchronous operation, and if using \ref boost_bind, you
+must specify only the arguments that match the handler's parameter list. In
+this program, both of the argument placeholders (asio::placeholders::error and
+asio::placeholders::bytes_transferred) could potentially have been removed.
+
+Start listening for the next client request.
+
+\until start_receive
+
+Any further actions for this client request are now the responsibility of
+<tt>handle_send()</tt>.
+
+\until }
+\until }
+
+The function <tt>handle_send()</tt> is invoked after the service request has
+been completed.
+
+\until }
+\until }
+
+See the \ref tutdaytime6src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime5 \n
+Next: \ref tutdaytime7
+
+*/
+
+/**
+\page tutdaytime6src Source listing for Daytime.6
+\include daytime6/server.cpp
+Return to \ref tutdaytime6
+*/
+
+/**
+\page tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server
+
+This tutorial program shows how to combine the two asynchronous servers that we
+have just written, into a single server application.
+
+\section tutdaytime7funcmain The main() function
+
+\dontinclude daytime7/server.cpp
+\skip int main()
+\until asio::io_service
+
+We will begin by creating a server object to accept a TCP client connection.
+
+\until tcp_server
+
+We also need a server object to accept a UDP client request.
+
+\until udp_server
+
+We have created two lots of work for the asio::io_service object to do.
+
+\until return 0;
+\until }
+
+\section tutdaytime7classtcp The tcp_connection and tcp_server classes
+
+The following two classes are taken from \ref tutdaytime3 "Daytime.3".
+
+\dontinclude daytime7/server.cpp
+\skip class tcp_connection
+\until };
+\until };
+
+\section tutdaytime7classudp The udp_server class
+
+Similarly, this next class is taken from the
+\ref tutdaytime6 "previous tutorial step".
+
+\dontinclude daytime7/server.cpp
+\skip class udp_server
+\until };
+
+See the \ref tutdaytime7src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tutdaytime6
+
+*/
+
+/**
+\page tutdaytime7src Source listing for Daytime.7
+\include daytime7/server.cpp
+Return to \ref tutdaytime7
+*/
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/index_dox.txt b/3rdparty/asio/src/examples/cpp03/tutorial/index_dox.txt
new file mode 100644
index 00000000000..7d3bd1a2912
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/index_dox.txt
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2003-2016 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)
+//
+
+/**
+\mainpage asio Tutorial
+
+\section tuttimer Basic Skills
+
+The tutorial programs in this first section introduce the fundamental concepts
+required to use the asio toolkit. Before plunging into the complex world of
+network programming, these tutorial programs illustrate the basic skills using
+simple asynchronous timers.
+
+\li \ref tuttimer1
+\li \ref tuttimer2
+\li \ref tuttimer3
+\li \ref tuttimer4
+\li \ref tuttimer5
+
+\section tutdaytime Introduction to Sockets
+
+The tutorial programs in this section show how to use asio to develop simple
+client and server programs. These tutorial programs are based around the <a
+href="http://www.ietf.org/rfc/rfc867.txt">daytime</a> protocol, which supports
+both TCP and UDP.
+
+The first three tutorial programs implement the daytime protocol using TCP.
+
+\li \ref tutdaytime1
+\li \ref tutdaytime2
+\li \ref tutdaytime3
+
+The next three tutorial programs implement the daytime protocol using UDP.
+
+\li \ref tutdaytime4
+\li \ref tutdaytime5
+\li \ref tutdaytime6
+
+The last tutorial program in this section demonstrates how asio allows the TCP
+and UDP servers to be easily combined into a single program.
+
+\li \ref tutdaytime7
+
+*/
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer1/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/timer1/.gitignore
new file mode 100644
index 00000000000..1d47ca67c43
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer1/.gitignore
@@ -0,0 +1,10 @@
+timer
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer1/timer.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/timer1/timer.cpp
new file mode 100644
index 00000000000..79ddf918261
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer1/timer.cpp
@@ -0,0 +1,25 @@
+//
+// timer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+int main()
+{
+ asio::io_context io;
+
+ asio::deadline_timer t(io, boost::posix_time::seconds(5));
+ t.wait();
+
+ std::cout << "Hello, world!" << std::endl;
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer2/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/timer2/.gitignore
new file mode 100644
index 00000000000..1d47ca67c43
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer2/.gitignore
@@ -0,0 +1,10 @@
+timer
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer2/timer.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/timer2/timer.cpp
new file mode 100644
index 00000000000..3275c22c2f6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer2/timer.cpp
@@ -0,0 +1,30 @@
+//
+// timer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+void print(const asio::error_code& /*e*/)
+{
+ std::cout << "Hello, world!" << std::endl;
+}
+
+int main()
+{
+ asio::io_context io;
+
+ asio::deadline_timer t(io, boost::posix_time::seconds(5));
+ t.async_wait(&print);
+
+ io.run();
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer3/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/timer3/.gitignore
new file mode 100644
index 00000000000..1d47ca67c43
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer3/.gitignore
@@ -0,0 +1,10 @@
+timer
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer3/timer.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/timer3/timer.cpp
new file mode 100644
index 00000000000..dfbf7d660a0
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer3/timer.cpp
@@ -0,0 +1,44 @@
+//
+// timer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+void print(const asio::error_code& /*e*/,
+ asio::deadline_timer* t, int* count)
+{
+ if (*count < 5)
+ {
+ std::cout << *count << std::endl;
+ ++(*count);
+
+ t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
+ t->async_wait(boost::bind(print,
+ asio::placeholders::error, t, count));
+ }
+}
+
+int main()
+{
+ asio::io_context io;
+
+ int count = 0;
+ asio::deadline_timer t(io, boost::posix_time::seconds(1));
+ t.async_wait(boost::bind(print,
+ asio::placeholders::error, &t, &count));
+
+ io.run();
+
+ std::cout << "Final count is " << count << std::endl;
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer4/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/timer4/.gitignore
new file mode 100644
index 00000000000..1d47ca67c43
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer4/.gitignore
@@ -0,0 +1,10 @@
+timer
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer4/timer.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/timer4/timer.cpp
new file mode 100644
index 00000000000..cbea70d26fa
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer4/timer.cpp
@@ -0,0 +1,55 @@
+//
+// timer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+class printer
+{
+public:
+ printer(asio::io_context& io)
+ : timer_(io, boost::posix_time::seconds(1)),
+ count_(0)
+ {
+ timer_.async_wait(boost::bind(&printer::print, this));
+ }
+
+ ~printer()
+ {
+ std::cout << "Final count is " << count_ << std::endl;
+ }
+
+ void print()
+ {
+ if (count_ < 5)
+ {
+ std::cout << count_ << std::endl;
+ ++count_;
+
+ timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
+ timer_.async_wait(boost::bind(&printer::print, this));
+ }
+ }
+
+private:
+ asio::deadline_timer timer_;
+ int count_;
+};
+
+int main()
+{
+ asio::io_context io;
+ printer p(io);
+ io.run();
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer5/.gitignore b/3rdparty/asio/src/examples/cpp03/tutorial/timer5/.gitignore
new file mode 100644
index 00000000000..1d47ca67c43
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer5/.gitignore
@@ -0,0 +1,10 @@
+timer
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer5/timer.cpp b/3rdparty/asio/src/examples/cpp03/tutorial/timer5/timer.cpp
new file mode 100644
index 00000000000..a798e85aacf
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer5/timer.cpp
@@ -0,0 +1,81 @@
+//
+// timer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+class printer
+{
+public:
+ printer(asio::io_context& io)
+ : strand_(io),
+ timer1_(io, boost::posix_time::seconds(1)),
+ timer2_(io, boost::posix_time::seconds(1)),
+ count_(0)
+ {
+ timer1_.async_wait(asio::bind_executor(strand_,
+ boost::bind(&printer::print1, this)));
+
+ timer2_.async_wait(asio::bind_executor(strand_,
+ boost::bind(&printer::print2, this)));
+ }
+
+ ~printer()
+ {
+ std::cout << "Final count is " << count_ << std::endl;
+ }
+
+ void print1()
+ {
+ if (count_ < 10)
+ {
+ std::cout << "Timer 1: " << count_ << std::endl;
+ ++count_;
+
+ timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
+
+ timer1_.async_wait(asio::bind_executor(strand_,
+ boost::bind(&printer::print1, this)));
+ }
+ }
+
+ void print2()
+ {
+ if (count_ < 10)
+ {
+ std::cout << "Timer 2: " << count_ << std::endl;
+ ++count_;
+
+ timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
+
+ timer2_.async_wait(asio::bind_executor(strand_,
+ boost::bind(&printer::print2, this)));
+ }
+ }
+
+private:
+ asio::io_context::strand strand_;
+ asio::deadline_timer timer1_;
+ asio::deadline_timer timer2_;
+ int count_;
+};
+
+int main()
+{
+ asio::io_context io;
+ printer p(io);
+ asio::thread t(boost::bind(&asio::io_context::run, &io));
+ io.run();
+ t.join();
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp03/tutorial/timer_dox.txt b/3rdparty/asio/src/examples/cpp03/tutorial/timer_dox.txt
new file mode 100644
index 00000000000..7c5a0a099a6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/tutorial/timer_dox.txt
@@ -0,0 +1,383 @@
+//
+// Copyright (c) 2003-2016 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)
+//
+
+/**
+\page tuttimer1 Timer.1 - Using a timer synchronously
+
+This tutorial program introduces asio by showing how to perform a blocking
+wait on a timer.
+
+\dontinclude timer1/timer.cpp
+\skip #include
+
+We start by including the necessary header files.
+
+All of the asio classes can be used by simply including the <tt>"asio.hpp"</tt>
+header file.
+
+\until asio.hpp
+
+Since this example uses timers, we need to include the appropriate
+Boost.Date_Time header file for manipulating times.
+
+\until posix_time.hpp
+
+All programs that use asio need to have at least one asio::io_service object.
+This class provides access to I/O functionality. We declare an object of this
+type first thing in the main function.
+
+\until asio::io_service
+
+Next we declare an object of type asio::deadline_timer. The core asio classes
+that provide I/O functionality (or as in this case timer functionality) always
+take a reference to an io_service as their first constructor argument. The
+second argument to the constructor sets the timer to expire 5 seconds from now.
+
+\until asio::deadline_timer
+
+In this simple example we perform a blocking wait on the timer.
+That is, the call to asio::deadline_timer::wait() will not return until the
+timer has expired, 5 seconds after it was created (i.e. <b>not</b> from when the
+wait starts).
+
+A deadline timer is always in one of two states: "expired" or "not expired". If
+the asio::deadline_timer::wait() function is called on an expired timer, it
+will return immediately.
+
+\until wait
+
+Finally we print the obligatory <tt>"Hello, world!"</tt>
+message to show when the timer has expired.
+
+\until }
+
+See the \ref tuttimer1src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Next: \ref tuttimer2
+
+*/
+
+/**
+\page tuttimer1src Source listing for Timer.1
+\include timer1/timer.cpp
+Return to \ref tuttimer1
+*/
+
+/**
+\page tuttimer2 Timer.2 - Using a timer asynchronously
+
+This tutorial program demonstrates how to use asio's asynchronous callback
+functionality by modifying the program from tutorial Timer.1 to perform an
+asynchronous wait on the timer.
+
+\dontinclude timer2/timer.cpp
+\skip #include
+
+\until posix_time.hpp
+
+Using asio's asynchronous functionality means having a callback
+function that will be called when an asynchronous operation completes. In this
+program we define a function called <tt>print</tt> to be called when the
+asynchronous wait finishes.
+
+\until asio::deadline_timer
+
+Next, instead of doing a blocking wait as in tutorial Timer.1,
+we call the asio::deadline_timer::async_wait() function to perform an
+asynchronous wait. When calling this function we pass the <tt>print</tt>
+callback handler that was defined above.
+
+\skipline async_wait
+
+Finally, we must call the asio::io_service::run() member function
+on the io_service object.
+
+The asio library provides a guarantee that callback handlers will <b>only</b>
+be called from threads that are currently calling asio::io_service::run().
+Therefore unless the asio::io_service::run() function is called the callback for
+the asynchronous wait completion will never be invoked.
+
+The asio::io_service::run() function will also continue to run while there is
+still "work" to do. In this example, the work is the asynchronous wait on the
+timer, so the call will not return until the timer has expired and the
+callback has completed.
+
+It is important to remember to give the io_service some work to do before
+calling asio::io_service::run(). For example, if we had omitted the above call
+to asio::deadline_timer::async_wait(), the io_service would not have had any
+work to do, and consequently asio::io_service::run() would have returned
+immediately.
+
+\skip run
+\until }
+
+See the \ref tuttimer2src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tuttimer1 \n
+Next: \ref tuttimer3
+
+*/
+
+/**
+\page tuttimer2src Source listing for Timer.2
+\include timer2/timer.cpp
+Return to \ref tuttimer2
+*/
+
+/**
+\page tuttimer3 Timer.3 - Binding arguments to a handler
+
+In this tutorial we will modify the program from tutorial Timer.2 so that the
+timer fires once a second. This will show how to pass additional parameters to
+your handler function.
+
+\dontinclude timer3/timer.cpp
+\skip #include
+
+\until posix_time.hpp
+
+To implement a repeating timer using asio you need to change
+the timer's expiry time in your callback function, and to then start a new
+asynchronous wait. Obviously this means that the callback function will need
+to be able to access the timer object. To this end we add two new parameters
+to the <tt>print</tt> function:
+
+\li A pointer to a timer object.
+
+\li A counter so that we can stop the program when the timer fires for the
+sixth time.
+
+\until {
+
+As mentioned above, this tutorial program uses a counter to
+stop running when the timer fires for the sixth time. However you will observe
+that there is no explicit call to ask the io_service to stop. Recall that in
+tutorial Timer.2 we learnt that the asio::io_service::run() function completes
+when there is no more "work" to do. By not starting a new asynchronous wait on
+the timer when <tt>count</tt> reaches 5, the io_service will run out of work and
+stop running.
+
+\until ++
+
+Next we move the expiry time for the timer along by one second
+from the previous expiry time. By calculating the new expiry time relative to
+the old, we can ensure that the timer does not drift away from the
+whole-second mark due to any delays in processing the handler.
+
+\until expires_at
+
+Then we start a new asynchronous wait on the timer. As you can
+see, the \ref boost_bind function is used to associate the extra parameters
+with your callback handler. The asio::deadline_timer::async_wait() function
+expects a handler function (or function object) with the signature
+<tt>void(const asio::error_code&)</tt>. Binding the additional parameters
+converts your <tt>print</tt> function into a function object that matches the
+signature correctly.
+
+See the <a href="http://www.boost.org/libs/bind/bind.html">Boost.Bind
+documentation</a> for more information on how to use \ref boost_bind.
+
+In this example, the asio::placeholders::error argument to \ref boost_bind is a
+named placeholder for the error object passed to the handler. When initiating
+the asynchronous operation, and if using \ref boost_bind, you must specify only
+the arguments that match the handler's parameter list. In tutorial Timer.4 you
+will see that this placeholder may be elided if the parameter is not needed by
+the callback handler.
+
+\until asio::io_service
+
+A new <tt>count</tt> variable is added so that we can stop the
+program when the timer fires for the sixth time.
+
+\until asio::deadline_timer
+
+As in Step 4, when making the call to
+asio::deadline_timer::async_wait() from <tt>main</tt> we bind the additional
+parameters needed for the <tt>print</tt> function.
+
+\until run
+
+Finally, just to prove that the <tt>count</tt> variable was
+being used in the <tt>print</tt> handler function, we will print out its new
+value.
+
+\until }
+
+See the \ref tuttimer3src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tuttimer2 \n
+Next: \ref tuttimer4
+
+*/
+
+/**
+\page tuttimer3src Source listing for Timer.3
+\include timer3/timer.cpp
+Return to \ref tuttimer3
+*/
+
+/**
+\page tuttimer4 Timer.4 - Using a member function as a handler
+
+In this tutorial we will see how to use a class member function as a callback
+handler. The program should execute identically to the tutorial program from
+tutorial Timer.3.
+
+\dontinclude timer4/timer.cpp
+\skip #include
+
+\until posix_time.hpp
+
+Instead of defining a free function <tt>print</tt> as the
+callback handler, as we did in the earlier tutorial programs, we now define a
+class called <tt>printer</tt>.
+
+\until public
+
+The constructor of this class will take a reference to the
+io_service object and use it when initialising the <tt>timer_</tt> member. The
+counter used to shut down the program is now also a member of the class.
+
+\until {
+
+The \ref boost_bind function works just as well with class
+member functions as with free functions. Since all non-static class member
+functions have an implicit <tt>this</tt> parameter, we need to bind
+<tt>this</tt> to the function. As in tutorial Timer.3, \ref boost_bind
+converts our callback handler (now a member function) into a function object
+that can be invoked as though it has the signature <tt>void(const
+asio::error_code&)</tt>.
+
+You will note that the asio::placeholders::error placeholder is not specified
+here, as the <tt>print</tt> member function does not accept an error object as
+a parameter.
+
+\until }
+
+In the class destructor we will print out the final value of
+the counter.
+
+\until }
+
+The <tt>print</tt> member function is very similar to the
+<tt>print</tt> function from tutorial Timer.3, except that it now operates on
+the class data members instead of having the timer and counter passed in as
+parameters.
+
+\until };
+
+The <tt>main</tt> function is much simpler than before, as it
+now declares a local <tt>printer</tt> object before running the io_service as
+normal.
+
+\until }
+
+See the \ref tuttimer4src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tuttimer3 \n
+Next: \ref tuttimer5 \n
+
+*/
+
+/**
+\page tuttimer4src Source listing for Timer.4
+\include timer4/timer.cpp
+Return to \ref tuttimer4
+*/
+
+/**
+\page tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs
+
+This tutorial demonstrates the use of the asio::io_service::strand class to
+synchronise callback handlers in a multithreaded program.
+
+The previous four tutorials avoided the issue of handler synchronisation by
+calling the asio::io_service::run() function from one thread only. As you
+already know, the asio library provides a guarantee that callback handlers will
+<b>only</b> be called from threads that are currently calling
+asio::io_service::run(). Consequently, calling asio::io_service::run() from
+only one thread ensures that callback handlers cannot run concurrently.
+
+The single threaded approach is usually the best place to start when
+developing applications using asio. The downside is the limitations it places
+on programs, particularly servers, including:
+
+<ul>
+<li>Poor responsiveness when handlers can take a long time to complete.</li>
+<li>An inability to scale on multiprocessor systems.</li>
+</ul>
+
+If you find yourself running into these limitations, an alternative approach
+is to have a pool of threads calling asio::io_service::run(). However, as this
+allows handlers to execute concurrently, we need a method of synchronisation
+when handlers might be accessing a shared, thread-unsafe resource.
+
+\dontinclude timer5/timer.cpp
+\skip #include
+
+\until posix_time.hpp
+
+We start by defining a class called <tt>printer</tt>, similar
+to the class in the previous tutorial. This class will extend the previous
+tutorial by running two timers in parallel.
+
+\until public
+
+In addition to initialising a pair of asio::deadline_timer members, the
+constructor initialises the <tt>strand_</tt> member, an object of type
+asio::io_service::strand.
+
+An asio::io_service::strand is an executor that guarantees that, for those
+handlers that are dispatched through it, an executing handler will be allowed
+to complete before the next one is started. This is guaranteed irrespective of
+the number of threads that are calling asio::io_service::run(). Of course, the
+handlers may still execute concurrently with other handlers that were
+<b>not</b> dispatched through an asio::io_service::strand, or were dispatched
+through a different asio::io_service::strand object.
+
+\until {
+
+When initiating the asynchronous operations, each callback handler is "bound"
+to an asio::io_service::strand object. The
+asio::io_service::strand::bind_executor() function returns a new handler that
+automatically dispatches its contained handler through the
+asio::io_service::strand object. By binding the handlers to the same
+asio::io_service::strand, we are ensuring that they cannot execute
+concurrently.
+
+\until }
+\until }
+
+In a multithreaded program, the handlers for asynchronous
+operations should be synchronised if they access shared resources. In this
+tutorial, the shared resources used by the handlers (<tt>print1</tt> and
+<tt>print2</tt>) are <tt>std::cout</tt> and the <tt>count_</tt> data member.
+
+\until };
+
+The <tt>main</tt> function now causes asio::io_service::run() to
+be called from two threads: the main thread and one additional thread. This is
+accomplished using an asio::thread object.
+
+Just as it would with a call from a single thread, concurrent calls to
+asio::io_service::run() will continue to execute while there is "work" left to
+do. The background thread will not exit until all asynchronous operations have
+completed.
+
+\until }
+
+See the \ref tuttimer5src "full source listing" \n
+Return to the \ref index "tutorial index" \n
+Previous: \ref tuttimer4 \n
+
+*/
+
+/**
+\page tuttimer5src Source listing for Timer.5
+\include timer5/timer.cpp
+Return to \ref tuttimer5
+*/
diff --git a/3rdparty/asio/src/examples/cpp03/windows/.gitignore b/3rdparty/asio/src/examples/cpp03/windows/.gitignore
new file mode 100644
index 00000000000..180ba886e58
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/windows/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp03/windows/transmit_file.cpp b/3rdparty/asio/src/examples/cpp03/windows/transmit_file.cpp
new file mode 100644
index 00000000000..8ca9e1790fc
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp03/windows/transmit_file.cpp
@@ -0,0 +1,171 @@
+//
+// transmit_file.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "asio.hpp"
+
+#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+
+using asio::ip::tcp;
+using asio::windows::overlapped_ptr;
+using asio::windows::random_access_handle;
+
+// A wrapper for the TransmitFile overlapped I/O operation.
+template <typename Handler>
+void transmit_file(tcp::socket& socket,
+ random_access_handle& file, Handler handler)
+{
+ // Construct an OVERLAPPED-derived object to contain the handler.
+ overlapped_ptr overlapped(socket.get_executor().context(), handler);
+
+ // Initiate the TransmitFile operation.
+ BOOL ok = ::TransmitFile(socket.native_handle(),
+ file.native_handle(), 0, 0, overlapped.get(), 0, 0);
+ DWORD last_error = ::GetLastError();
+
+ // Check if the operation completed immediately.
+ if (!ok && last_error != ERROR_IO_PENDING)
+ {
+ // The operation completed immediately, so a completion notification needs
+ // to be posted. When complete() is called, ownership of the OVERLAPPED-
+ // derived object passes to the io_context.
+ asio::error_code ec(last_error,
+ asio::error::get_system_category());
+ overlapped.complete(ec, 0);
+ }
+ else
+ {
+ // The operation was successfully initiated, so ownership of the
+ // OVERLAPPED-derived object has passed to the io_context.
+ overlapped.release();
+ }
+}
+
+class connection
+ : public boost::enable_shared_from_this<connection>
+{
+public:
+ typedef boost::shared_ptr<connection> pointer;
+
+ static pointer create(asio::io_context& io_context,
+ const std::string& filename)
+ {
+ return pointer(new connection(io_context, filename));
+ }
+
+ tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ asio::error_code ec;
+ file_.assign(::CreateFile(filename_.c_str(), GENERIC_READ, 0, 0,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0), ec);
+ if (file_.is_open())
+ {
+ transmit_file(socket_, file_,
+ boost::bind(&connection::handle_write, shared_from_this(),
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
+ }
+ }
+
+private:
+ connection(asio::io_context& io_context, const std::string& filename)
+ : socket_(io_context),
+ filename_(filename),
+ file_(io_context)
+ {
+ }
+
+ void handle_write(const asio::error_code& /*error*/,
+ size_t /*bytes_transferred*/)
+ {
+ asio::error_code ignored_ec;
+ socket_.shutdown(tcp::socket::shutdown_both, ignored_ec);
+ }
+
+ tcp::socket socket_;
+ std::string filename_;
+ random_access_handle file_;
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context,
+ unsigned short port, const std::string& filename)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
+ filename_(filename)
+ {
+ start_accept();
+ }
+
+private:
+ void start_accept()
+ {
+ connection::pointer new_connection =
+ connection::create(acceptor_.get_executor().context(), filename_);
+
+ acceptor_.async_accept(new_connection->socket(),
+ boost::bind(&server::handle_accept, this, new_connection,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(connection::pointer new_connection,
+ const asio::error_code& error)
+ {
+ if (!error)
+ {
+ new_connection->start();
+ }
+
+ start_accept();
+ }
+
+ tcp::acceptor acceptor_;
+ std::string filename_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: transmit_file <port> <filename>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ using namespace std; // For atoi.
+ server s(io_context, atoi(argv[1]), argv[2]);
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
+
+#else // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+# error Overlapped I/O not available on this platform
+#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
diff --git a/3rdparty/asio/src/examples/cpp11/Makefile.am b/3rdparty/asio/src/examples/cpp11/Makefile.am
new file mode 100644
index 00000000000..182c711229f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/Makefile.am
@@ -0,0 +1,92 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+if SEPARATE_COMPILATION
+noinst_LIBRARIES = libasio.a
+libasio_a_SOURCES = ../../asio.cpp
+if HAVE_OPENSSL
+libasio_a_SOURCES += ../../asio_ssl.cpp
+endif
+LDADD = libasio.a
+endif
+
+noinst_PROGRAMS = \
+ allocation/server \
+ buffers/reference_counted \
+ chat/chat_client \
+ chat/chat_server \
+ echo/async_tcp_echo_server \
+ echo/async_udp_echo_server \
+ echo/blocking_tcp_echo_client \
+ echo/blocking_tcp_echo_server \
+ echo/blocking_udp_echo_client \
+ echo/blocking_udp_echo_server \
+ executors/actor \
+ executors/bank_account_1 \
+ executors/bank_account_2 \
+ executors/fork_join \
+ executors/pipeline \
+ executors/priority_scheduler \
+ futures/daytime_client \
+ http/server/http_server \
+ iostreams/http_client
+
+if HAVE_BOOST_COROUTINE
+noinst_PROGRAMS += \
+ spawn/echo_server \
+ spawn/parallel_grep
+endif
+
+noinst_HEADERS = \
+ chat/chat_message.hpp
+
+AM_CXXFLAGS = -I$(srcdir)/../../../include
+
+allocation_server_SOURCES = allocation/server.cpp
+buffers_reference_counted_SOURCES = buffers/reference_counted.cpp
+chat_chat_client_SOURCES = chat/chat_client.cpp
+chat_chat_server_SOURCES = chat/chat_server.cpp
+echo_async_tcp_echo_server_SOURCES = echo/async_tcp_echo_server.cpp
+echo_async_udp_echo_server_SOURCES = echo/async_udp_echo_server.cpp
+echo_blocking_tcp_echo_client_SOURCES = echo/blocking_tcp_echo_client.cpp
+echo_blocking_tcp_echo_server_SOURCES = echo/blocking_tcp_echo_server.cpp
+echo_blocking_udp_echo_client_SOURCES = echo/blocking_udp_echo_client.cpp
+echo_blocking_udp_echo_server_SOURCES = echo/blocking_udp_echo_server.cpp
+executors_actor_SOURCES = executors/actor.cpp
+executors_bank_account_1_SOURCES = executors/bank_account_1.cpp
+executors_bank_account_2_SOURCES = executors/bank_account_2.cpp
+executors_fork_join_SOURCES = executors/fork_join.cpp
+executors_pipeline_SOURCES = executors/pipeline.cpp
+executors_priority_scheduler_SOURCES = executors/priority_scheduler.cpp
+futures_daytime_client_SOURCES = futures/daytime_client.cpp
+http_server_http_server_SOURCES = \
+ http/server/connection.cpp \
+ http/server/connection_manager.cpp \
+ http/server/main.cpp \
+ http/server/mime_types.cpp \
+ http/server/reply.cpp \
+ http/server/request_handler.cpp \
+ http/server/request_parser.cpp \
+ http/server/server.cpp
+iostreams_http_client_SOURCES = iostreams/http_client.cpp
+
+if HAVE_BOOST_COROUTINE
+spawn_echo_server_SOURCES = spawn/echo_server.cpp
+spawn_echo_server_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system
+spawn_parallel_grep_SOURCES = spawn/parallel_grep.cpp
+spawn_parallel_grep_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system
+endif
+
+EXTRA_DIST = \
+ handler_tracking/custom_tracking.hpp \
+ http/server/connection.hpp \
+ http/server/connection_manager.hpp \
+ http/server/header.hpp \
+ http/server/mime_types.hpp \
+ http/server/reply.hpp \
+ http/server/request.hpp \
+ http/server/request_handler.hpp \
+ http/server/request_parser.hpp \
+ http/server/server.hpp
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
diff --git a/3rdparty/asio/src/examples/cpp11/allocation/.gitignore b/3rdparty/asio/src/examples/cpp11/allocation/.gitignore
new file mode 100644
index 00000000000..180ba886e58
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/allocation/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/allocation/server.cpp b/3rdparty/asio/src/examples/cpp11/allocation/server.cpp
new file mode 100644
index 00000000000..cbcbe76fe68
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/allocation/server.cpp
@@ -0,0 +1,213 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <array>
+#include <cstdlib>
+#include <iostream>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+// Class to manage the memory to be used for handler-based custom allocation.
+// It contains a single block of memory which may be returned for allocation
+// requests. If the memory is in use when an allocation request is made, the
+// allocator delegates allocation to the global heap.
+class handler_allocator
+{
+public:
+ handler_allocator()
+ : in_use_(false)
+ {
+ }
+
+ handler_allocator(const handler_allocator&) = delete;
+ handler_allocator& operator=(const handler_allocator&) = delete;
+
+ void* allocate(std::size_t size)
+ {
+ if (!in_use_ && size < sizeof(storage_))
+ {
+ in_use_ = true;
+ return &storage_;
+ }
+ else
+ {
+ return ::operator new(size);
+ }
+ }
+
+ void deallocate(void* pointer)
+ {
+ if (pointer == &storage_)
+ {
+ in_use_ = false;
+ }
+ else
+ {
+ ::operator delete(pointer);
+ }
+ }
+
+private:
+ // Storage space used for handler-based custom memory allocation.
+ typename std::aligned_storage<1024>::type storage_;
+
+ // Whether the handler-based custom allocation storage has been used.
+ bool in_use_;
+};
+
+// Wrapper class template for handler objects to allow handler memory
+// allocation to be customised. Calls to operator() are forwarded to the
+// encapsulated handler.
+template <typename Handler>
+class custom_alloc_handler
+{
+public:
+ custom_alloc_handler(handler_allocator& a, Handler h)
+ : allocator_(a),
+ handler_(h)
+ {
+ }
+
+ template <typename ...Args>
+ void operator()(Args&&... args)
+ {
+ handler_(std::forward<Args>(args)...);
+ }
+
+ friend void* asio_handler_allocate(std::size_t size,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ return this_handler->allocator_.allocate(size);
+ }
+
+ friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ this_handler->allocator_.deallocate(pointer);
+ }
+
+private:
+ handler_allocator& allocator_;
+ Handler handler_;
+};
+
+// Helper function to wrap a handler object to add custom allocation.
+template <typename Handler>
+inline custom_alloc_handler<Handler> make_custom_alloc_handler(
+ handler_allocator& a, Handler h)
+{
+ return custom_alloc_handler<Handler>(a, h);
+}
+
+class session
+ : public std::enable_shared_from_this<session>
+{
+public:
+ session(tcp::socket socket)
+ : socket_(std::move(socket))
+ {
+ }
+
+ void start()
+ {
+ do_read();
+ }
+
+private:
+ void do_read()
+ {
+ auto self(shared_from_this());
+ socket_.async_read_some(asio::buffer(data_),
+ make_custom_alloc_handler(allocator_,
+ [this, self](std::error_code ec, std::size_t length)
+ {
+ if (!ec)
+ {
+ do_write(length);
+ }
+ }));
+ }
+
+ void do_write(std::size_t length)
+ {
+ auto self(shared_from_this());
+ asio::async_write(socket_, asio::buffer(data_, length),
+ make_custom_alloc_handler(allocator_,
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ do_read();
+ }
+ }));
+ }
+
+ // The socket used to communicate with the client.
+ tcp::socket socket_;
+
+ // Buffer used to store data received from the client.
+ std::array<char, 1024> data_;
+
+ // The allocator to use for handler-based custom memory allocation.
+ handler_allocator allocator_;
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ do_accept();
+ }
+
+private:
+ void do_accept()
+ {
+ acceptor_.async_accept(
+ [this](std::error_code ec, tcp::socket socket)
+ {
+ if (!ec)
+ {
+ std::make_shared<session>(std::move(socket))->start();
+ }
+
+ do_accept();
+ });
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+ server s(io_context, std::atoi(argv[1]));
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/buffers/.gitignore b/3rdparty/asio/src/examples/cpp11/buffers/.gitignore
new file mode 100644
index 00000000000..abe68c665f5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/buffers/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+reference_counted
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/buffers/reference_counted.cpp b/3rdparty/asio/src/examples/cpp11/buffers/reference_counted.cpp
new file mode 100644
index 00000000000..34fe9090dfd
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/buffers/reference_counted.cpp
@@ -0,0 +1,121 @@
+//
+// reference_counted.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio.hpp>
+#include <iostream>
+#include <memory>
+#include <utility>
+#include <vector>
+
+using asio::ip::tcp;
+
+// A reference-counted non-modifiable buffer class.
+class shared_const_buffer
+{
+public:
+ // Construct from a std::string.
+ explicit shared_const_buffer(const std::string& data)
+ : data_(new std::vector<char>(data.begin(), data.end())),
+ buffer_(asio::buffer(*data_))
+ {
+ }
+
+ // Implement the ConstBufferSequence requirements.
+ typedef asio::const_buffer value_type;
+ typedef const asio::const_buffer* const_iterator;
+ const asio::const_buffer* begin() const { return &buffer_; }
+ const asio::const_buffer* end() const { return &buffer_ + 1; }
+
+private:
+ std::shared_ptr<std::vector<char> > data_;
+ asio::const_buffer buffer_;
+};
+
+class session
+ : public std::enable_shared_from_this<session>
+{
+public:
+ session(tcp::socket socket)
+ : socket_(std::move(socket))
+ {
+ }
+
+ void start()
+ {
+ do_write();
+ }
+
+private:
+ void do_write()
+ {
+ std::time_t now = std::time(0);
+ shared_const_buffer buffer(std::ctime(&now));
+
+ auto self(shared_from_this());
+ asio::async_write(socket_, buffer,
+ [this, self](std::error_code /*ec*/, std::size_t /*length*/)
+ {
+ });
+ }
+
+ // The socket used to communicate with the client.
+ tcp::socket socket_;
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ do_accept();
+ }
+
+private:
+ void do_accept()
+ {
+ acceptor_.async_accept(
+ [this](std::error_code ec, tcp::socket socket)
+ {
+ if (!ec)
+ {
+ std::make_shared<session>(std::move(socket))->start();
+ }
+
+ do_accept();
+ });
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: reference_counted <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server s(io_context, std::atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/chat/.gitignore b/3rdparty/asio/src/examples/cpp11/chat/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/chat/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/chat/chat_client.cpp b/3rdparty/asio/src/examples/cpp11/chat/chat_client.cpp
new file mode 100644
index 00000000000..e672a022d04
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/chat/chat_client.cpp
@@ -0,0 +1,167 @@
+//
+// chat_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <thread>
+#include "asio.hpp"
+#include "chat_message.hpp"
+
+using asio::ip::tcp;
+
+typedef std::deque<chat_message> chat_message_queue;
+
+class chat_client
+{
+public:
+ chat_client(asio::io_context& io_context,
+ const tcp::resolver::results_type& endpoints)
+ : io_context_(io_context),
+ socket_(io_context)
+ {
+ do_connect(endpoints);
+ }
+
+ void write(const chat_message& msg)
+ {
+ asio::post(io_context_,
+ [this, msg]()
+ {
+ bool write_in_progress = !write_msgs_.empty();
+ write_msgs_.push_back(msg);
+ if (!write_in_progress)
+ {
+ do_write();
+ }
+ });
+ }
+
+ void close()
+ {
+ asio::post(io_context_, [this]() { socket_.close(); });
+ }
+
+private:
+ void do_connect(const tcp::resolver::results_type& endpoints)
+ {
+ asio::async_connect(socket_, endpoints,
+ [this](std::error_code ec, tcp::endpoint)
+ {
+ if (!ec)
+ {
+ do_read_header();
+ }
+ });
+ }
+
+ void do_read_header()
+ {
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ [this](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec && read_msg_.decode_header())
+ {
+ do_read_body();
+ }
+ else
+ {
+ socket_.close();
+ }
+ });
+ }
+
+ void do_read_body()
+ {
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ [this](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ std::cout.write(read_msg_.body(), read_msg_.body_length());
+ std::cout << "\n";
+ do_read_header();
+ }
+ else
+ {
+ socket_.close();
+ }
+ });
+ }
+
+ void do_write()
+ {
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ [this](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ write_msgs_.pop_front();
+ if (!write_msgs_.empty())
+ {
+ do_write();
+ }
+ }
+ else
+ {
+ socket_.close();
+ }
+ });
+ }
+
+private:
+ asio::io_context& io_context_;
+ tcp::socket socket_;
+ chat_message read_msg_;
+ chat_message_queue write_msgs_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: chat_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::resolver resolver(io_context);
+ auto endpoints = resolver.resolve(argv[1], argv[2]);
+ chat_client c(io_context, endpoints);
+
+ std::thread t([&io_context](){ io_context.run(); });
+
+ char line[chat_message::max_body_length + 1];
+ while (std::cin.getline(line, chat_message::max_body_length + 1))
+ {
+ chat_message msg;
+ msg.body_length(std::strlen(line));
+ std::memcpy(msg.body(), line, msg.body_length());
+ msg.encode_header();
+ c.write(msg);
+ }
+
+ c.close();
+ t.join();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/chat/chat_message.hpp b/3rdparty/asio/src/examples/cpp11/chat/chat_message.hpp
new file mode 100644
index 00000000000..f6e949bf2e2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/chat/chat_message.hpp
@@ -0,0 +1,91 @@
+//
+// chat_message.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 CHAT_MESSAGE_HPP
+#define CHAT_MESSAGE_HPP
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+class chat_message
+{
+public:
+ enum { header_length = 4 };
+ enum { max_body_length = 512 };
+
+ chat_message()
+ : body_length_(0)
+ {
+ }
+
+ const char* data() const
+ {
+ return data_;
+ }
+
+ char* data()
+ {
+ return data_;
+ }
+
+ std::size_t length() const
+ {
+ return header_length + body_length_;
+ }
+
+ const char* body() const
+ {
+ return data_ + header_length;
+ }
+
+ char* body()
+ {
+ return data_ + header_length;
+ }
+
+ std::size_t body_length() const
+ {
+ return body_length_;
+ }
+
+ void body_length(std::size_t new_length)
+ {
+ body_length_ = new_length;
+ if (body_length_ > max_body_length)
+ body_length_ = max_body_length;
+ }
+
+ bool decode_header()
+ {
+ char header[header_length + 1] = "";
+ std::strncat(header, data_, header_length);
+ body_length_ = std::atoi(header);
+ if (body_length_ > max_body_length)
+ {
+ body_length_ = 0;
+ return false;
+ }
+ return true;
+ }
+
+ void encode_header()
+ {
+ char header[header_length + 1] = "";
+ std::sprintf(header, "%4d", static_cast<int>(body_length_));
+ std::memcpy(data_, header, header_length);
+ }
+
+private:
+ char data_[header_length + max_body_length];
+ std::size_t body_length_;
+};
+
+#endif // CHAT_MESSAGE_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/chat/chat_server.cpp b/3rdparty/asio/src/examples/cpp11/chat/chat_server.cpp
new file mode 100644
index 00000000000..6e5ba3b8ee2
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/chat/chat_server.cpp
@@ -0,0 +1,227 @@
+//
+// chat_server.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <list>
+#include <memory>
+#include <set>
+#include <utility>
+#include "asio.hpp"
+#include "chat_message.hpp"
+
+using asio::ip::tcp;
+
+//----------------------------------------------------------------------
+
+typedef std::deque<chat_message> chat_message_queue;
+
+//----------------------------------------------------------------------
+
+class chat_participant
+{
+public:
+ virtual ~chat_participant() {}
+ virtual void deliver(const chat_message& msg) = 0;
+};
+
+typedef std::shared_ptr<chat_participant> chat_participant_ptr;
+
+//----------------------------------------------------------------------
+
+class chat_room
+{
+public:
+ void join(chat_participant_ptr participant)
+ {
+ participants_.insert(participant);
+ for (auto msg: recent_msgs_)
+ participant->deliver(msg);
+ }
+
+ void leave(chat_participant_ptr participant)
+ {
+ participants_.erase(participant);
+ }
+
+ void deliver(const chat_message& msg)
+ {
+ recent_msgs_.push_back(msg);
+ while (recent_msgs_.size() > max_recent_msgs)
+ recent_msgs_.pop_front();
+
+ for (auto participant: participants_)
+ participant->deliver(msg);
+ }
+
+private:
+ std::set<chat_participant_ptr> participants_;
+ enum { max_recent_msgs = 100 };
+ chat_message_queue recent_msgs_;
+};
+
+//----------------------------------------------------------------------
+
+class chat_session
+ : public chat_participant,
+ public std::enable_shared_from_this<chat_session>
+{
+public:
+ chat_session(tcp::socket socket, chat_room& room)
+ : socket_(std::move(socket)),
+ room_(room)
+ {
+ }
+
+ void start()
+ {
+ room_.join(shared_from_this());
+ do_read_header();
+ }
+
+ void deliver(const chat_message& msg)
+ {
+ bool write_in_progress = !write_msgs_.empty();
+ write_msgs_.push_back(msg);
+ if (!write_in_progress)
+ {
+ do_write();
+ }
+ }
+
+private:
+ void do_read_header()
+ {
+ auto self(shared_from_this());
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.data(), chat_message::header_length),
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec && read_msg_.decode_header())
+ {
+ do_read_body();
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ });
+ }
+
+ void do_read_body()
+ {
+ auto self(shared_from_this());
+ asio::async_read(socket_,
+ asio::buffer(read_msg_.body(), read_msg_.body_length()),
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ room_.deliver(read_msg_);
+ do_read_header();
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ });
+ }
+
+ void do_write()
+ {
+ auto self(shared_from_this());
+ asio::async_write(socket_,
+ asio::buffer(write_msgs_.front().data(),
+ write_msgs_.front().length()),
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ write_msgs_.pop_front();
+ if (!write_msgs_.empty())
+ {
+ do_write();
+ }
+ }
+ else
+ {
+ room_.leave(shared_from_this());
+ }
+ });
+ }
+
+ tcp::socket socket_;
+ chat_room& room_;
+ chat_message read_msg_;
+ chat_message_queue write_msgs_;
+};
+
+//----------------------------------------------------------------------
+
+class chat_server
+{
+public:
+ chat_server(asio::io_context& io_context,
+ const tcp::endpoint& endpoint)
+ : acceptor_(io_context, endpoint)
+ {
+ do_accept();
+ }
+
+private:
+ void do_accept()
+ {
+ acceptor_.async_accept(
+ [this](std::error_code ec, tcp::socket socket)
+ {
+ if (!ec)
+ {
+ std::make_shared<chat_session>(std::move(socket), room_)->start();
+ }
+
+ do_accept();
+ });
+ }
+
+ tcp::acceptor acceptor_;
+ chat_room room_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc < 2)
+ {
+ std::cerr << "Usage: chat_server <port> [<port> ...]\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ std::list<chat_server> servers;
+ for (int i = 1; i < argc; ++i)
+ {
+ tcp::endpoint endpoint(tcp::v4(), std::atoi(argv[i]));
+ servers.emplace_back(io_context, endpoint);
+ }
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/.gitignore b/3rdparty/asio/src/examples/cpp11/echo/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp
new file mode 100644
index 00000000000..d76ebe94aae
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp
@@ -0,0 +1,114 @@
+//
+// async_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <memory>
+#include <utility>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+class session
+ : public std::enable_shared_from_this<session>
+{
+public:
+ session(tcp::socket socket)
+ : socket_(std::move(socket))
+ {
+ }
+
+ void start()
+ {
+ do_read();
+ }
+
+private:
+ void do_read()
+ {
+ auto self(shared_from_this());
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ [this, self](std::error_code ec, std::size_t length)
+ {
+ if (!ec)
+ {
+ do_write(length);
+ }
+ });
+ }
+
+ void do_write(std::size_t length)
+ {
+ auto self(shared_from_this());
+ asio::async_write(socket_, asio::buffer(data_, length),
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ do_read();
+ }
+ });
+ }
+
+ tcp::socket socket_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+ {
+ do_accept();
+ }
+
+private:
+ void do_accept()
+ {
+ acceptor_.async_accept(
+ [this](std::error_code ec, tcp::socket socket)
+ {
+ if (!ec)
+ {
+ std::make_shared<session>(std::move(socket))->start();
+ }
+
+ do_accept();
+ });
+ }
+
+ tcp::acceptor acceptor_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server s(io_context, std::atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/async_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp11/echo/async_udp_echo_server.cpp
new file mode 100644
index 00000000000..8eb1b37f8b6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/async_udp_echo_server.cpp
@@ -0,0 +1,82 @@
+//
+// async_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : socket_(io_context, udp::endpoint(udp::v4(), port))
+ {
+ do_receive();
+ }
+
+ void do_receive()
+ {
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ [this](std::error_code ec, std::size_t bytes_recvd)
+ {
+ if (!ec && bytes_recvd > 0)
+ {
+ do_send(bytes_recvd);
+ }
+ else
+ {
+ do_receive();
+ }
+ });
+ }
+
+ void do_send(std::size_t length)
+ {
+ socket_.async_send_to(
+ asio::buffer(data_, length), sender_endpoint_,
+ [this](std::error_code /*ec*/, std::size_t /*bytes_sent*/)
+ {
+ do_receive();
+ });
+ }
+
+private:
+ udp::socket socket_;
+ udp::endpoint sender_endpoint_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server s(io_context, std::atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp b/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp
new file mode 100644
index 00000000000..c7c648df97f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp
@@ -0,0 +1,55 @@
+//
+// blocking_tcp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::socket s(io_context);
+ tcp::resolver resolver(io_context);
+ asio::connect(s, resolver.resolve(argv[1], argv[2]));
+
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = std::strlen(request);
+ asio::write(s, asio::buffer(request, request_length));
+
+ char reply[max_length];
+ size_t reply_length = asio::read(s,
+ asio::buffer(reply, request_length));
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp
new file mode 100644
index 00000000000..84a72d44453
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp
@@ -0,0 +1,74 @@
+//
+// blocking_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <thread>
+#include <utility>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+const int max_length = 1024;
+
+void session(tcp::socket sock)
+{
+ try
+ {
+ for (;;)
+ {
+ char data[max_length];
+
+ asio::error_code error;
+ size_t length = sock.read_some(asio::buffer(data), error);
+ if (error == asio::error::eof)
+ break; // Connection closed cleanly by peer.
+ else if (error)
+ throw asio::system_error(error); // Some other error.
+
+ asio::write(sock, asio::buffer(data, length));
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception in thread: " << e.what() << "\n";
+ }
+}
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
+ for (;;)
+ {
+ std::thread(session, a.accept()).detach();
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server(io_context, std::atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp b/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp
new file mode 100644
index 00000000000..1d15780c429
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp
@@ -0,0 +1,58 @@
+//
+// blocking_udp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_udp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ udp::socket s(io_context, udp::endpoint(udp::v4(), 0));
+
+ udp::resolver resolver(io_context);
+ udp::resolver::results_type endpoints =
+ resolver.resolve(udp::v4(), argv[1], argv[2]);
+
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = std::strlen(request);
+ s.send_to(asio::buffer(request, request_length), *endpoints.begin());
+
+ char reply[max_length];
+ udp::endpoint sender_endpoint;
+ size_t reply_length = s.receive_from(
+ asio::buffer(reply, max_length), sender_endpoint);
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_server.cpp
new file mode 100644
index 00000000000..8bb51735f26
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/echo/blocking_udp_echo_server.cpp
@@ -0,0 +1,52 @@
+//
+// blocking_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ udp::socket sock(io_context, udp::endpoint(udp::v4(), port));
+ for (;;)
+ {
+ char data[max_length];
+ udp::endpoint sender_endpoint;
+ size_t length = sock.receive_from(
+ asio::buffer(data, max_length), sender_endpoint);
+ sock.send_to(asio::buffer(data, length), sender_endpoint);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server(io_context, std::atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/.gitignore b/3rdparty/asio/src/examples/cpp11/executors/.gitignore
new file mode 100644
index 00000000000..183cecf7165
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/.gitignore
@@ -0,0 +1,5 @@
+actor
+bank_account_[0-9]
+fork_join
+pipeline
+priority_scheduler
diff --git a/3rdparty/asio/src/examples/cpp11/executors/actor.cpp b/3rdparty/asio/src/examples/cpp11/executors/actor.cpp
new file mode 100644
index 00000000000..22dbf206a17
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/actor.cpp
@@ -0,0 +1,286 @@
+#include <asio/defer.hpp>
+#include <asio/executor.hpp>
+#include <asio/post.hpp>
+#include <asio/strand.hpp>
+#include <asio/system_executor.hpp>
+#include <condition_variable>
+#include <deque>
+#include <memory>
+#include <mutex>
+#include <typeinfo>
+#include <vector>
+
+using asio::defer;
+using asio::executor;
+using asio::post;
+using asio::strand;
+using asio::system_executor;
+
+//------------------------------------------------------------------------------
+// A tiny actor framework
+// ~~~~~~~~~~~~~~~~~~~~~~
+
+class actor;
+
+// Used to identify the sender and recipient of messages.
+typedef actor* actor_address;
+
+// Base class for all registered message handlers.
+class message_handler_base
+{
+public:
+ virtual ~message_handler_base() {}
+
+ // Used to determine which message handlers receive an incoming message.
+ virtual const std::type_info& message_id() const = 0;
+};
+
+// Base class for a handler for a specific message type.
+template <class Message>
+class message_handler : public message_handler_base
+{
+public:
+ // Handle an incoming message.
+ virtual void handle_message(Message msg, actor_address from) = 0;
+};
+
+// Concrete message handler for a specific message type.
+template <class Actor, class Message>
+class mf_message_handler : public message_handler<Message>
+{
+public:
+ // Construct a message handler to invoke the specified member function.
+ mf_message_handler(void (Actor::* mf)(Message, actor_address), Actor* a)
+ : function_(mf), actor_(a)
+ {
+ }
+
+ // Used to determine which message handlers receive an incoming message.
+ virtual const std::type_info& message_id() const
+ {
+ return typeid(Message);
+ }
+
+ // Handle an incoming message.
+ virtual void handle_message(Message msg, actor_address from)
+ {
+ (actor_->*function_)(std::move(msg), from);
+ }
+
+ // Determine whether the message handler represents the specified function.
+ bool is_function(void (Actor::* mf)(Message, actor_address)) const
+ {
+ return mf == function_;
+ }
+
+private:
+ void (Actor::* function_)(Message, actor_address);
+ Actor* actor_;
+};
+
+// Base class for all actors.
+class actor
+{
+public:
+ virtual ~actor()
+ {
+ }
+
+ // Obtain the actor's address for use as a message sender or recipient.
+ actor_address address()
+ {
+ return this;
+ }
+
+ // Send a message from one actor to another.
+ template <class Message>
+ friend void send(Message msg, actor_address from, actor_address to)
+ {
+ // Execute the message handler in the context of the target's executor.
+ post(to->executor_,
+ [=]
+ {
+ to->call_handler(std::move(msg), from);
+ });
+ }
+
+protected:
+ // Construct the actor to use the specified executor for all message handlers.
+ actor(executor e)
+ : executor_(std::move(e))
+ {
+ }
+
+ // Register a handler for a specific message type. Duplicates are permitted.
+ template <class Actor, class Message>
+ void register_handler(void (Actor::* mf)(Message, actor_address))
+ {
+ handlers_.push_back(
+ std::make_shared<mf_message_handler<Actor, Message>>(
+ mf, static_cast<Actor*>(this)));
+ }
+
+ // Deregister a handler. Removes only the first matching handler.
+ template <class Actor, class Message>
+ void deregister_handler(void (Actor::* mf)(Message, actor_address))
+ {
+ const std::type_info& id = typeid(message_handler<Message>);
+ for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter)
+ {
+ if ((*iter)->message_id() == id)
+ {
+ auto mh = static_cast<mf_message_handler<Actor, Message>*>(iter->get());
+ if (mh->is_function(mf))
+ {
+ handlers_.erase(iter);
+ return;
+ }
+ }
+ }
+ }
+
+ // Send a message from within a message handler.
+ template <class Message>
+ void tail_send(Message msg, actor_address to)
+ {
+ // Execute the message handler in the context of the target's executor.
+ actor* from = this;
+ defer(to->executor_,
+ [=]
+ {
+ to->call_handler(std::move(msg), from);
+ });
+ }
+
+private:
+ // Find the matching message handlers, if any, and call them.
+ template <class Message>
+ void call_handler(Message msg, actor_address from)
+ {
+ const std::type_info& message_id = typeid(Message);
+ for (auto& h: handlers_)
+ {
+ if (h->message_id() == message_id)
+ {
+ auto mh = static_cast<message_handler<Message>*>(h.get());
+ mh->handle_message(msg, from);
+ }
+ }
+ }
+
+ // All messages associated with a single actor object should be processed
+ // non-concurrently. We use a strand to ensure non-concurrent execution even
+ // if the underlying executor may use multiple threads.
+ strand<executor> executor_;
+
+ std::vector<std::shared_ptr<message_handler_base>> handlers_;
+};
+
+// A concrete actor that allows synchronous message retrieval.
+template <class Message>
+class receiver : public actor
+{
+public:
+ receiver()
+ : actor(system_executor())
+ {
+ register_handler(&receiver::message_handler);
+ }
+
+ // Block until a message has been received.
+ Message wait()
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ condition_.wait(lock, [this]{ return !message_queue_.empty(); });
+ Message msg(std::move(message_queue_.front()));
+ message_queue_.pop_front();
+ return msg;
+ }
+
+private:
+ // Handle a new message by adding it to the queue and waking a waiter.
+ void message_handler(Message msg, actor_address /* from */)
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ message_queue_.push_back(std::move(msg));
+ condition_.notify_one();
+ }
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::deque<Message> message_queue_;
+};
+
+//------------------------------------------------------------------------------
+
+#include <asio/thread_pool.hpp>
+#include <iostream>
+
+using asio::thread_pool;
+
+class member : public actor
+{
+public:
+ explicit member(executor e)
+ : actor(std::move(e))
+ {
+ register_handler(&member::init_handler);
+ }
+
+private:
+ void init_handler(actor_address next, actor_address from)
+ {
+ next_ = next;
+ caller_ = from;
+
+ register_handler(&member::token_handler);
+ deregister_handler(&member::init_handler);
+ }
+
+ void token_handler(int token, actor_address /*from*/)
+ {
+ int msg(token);
+ actor_address to(caller_);
+
+ if (token > 0)
+ {
+ msg = token - 1;
+ to = next_;
+ }
+
+ tail_send(msg, to);
+ }
+
+ actor_address next_;
+ actor_address caller_;
+};
+
+int main()
+{
+ const std::size_t num_threads = 16;
+ const int num_hops = 50000000;
+ const std::size_t num_actors = 503;
+ const int token_value = (num_hops + num_actors - 1) / num_actors;
+ const std::size_t actors_per_thread = num_actors / num_threads;
+
+ struct single_thread_pool : thread_pool { single_thread_pool() : thread_pool(1) {} };
+ single_thread_pool pools[num_threads];
+ std::vector<std::shared_ptr<member>> members(num_actors);
+ receiver<int> rcvr;
+
+ // Create the member actors.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ members[i] = std::make_shared<member>(pools[(i / actors_per_thread) % num_threads].get_executor());
+
+ // Initialise the actors by passing each one the address of the next actor in the ring.
+ for (std::size_t i = num_actors, next_i = 0; i > 0; next_i = --i)
+ send(members[next_i]->address(), rcvr.address(), members[i - 1]->address());
+
+ // Send exactly one token to each actor, all with the same initial value, rounding up if required.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ send(token_value, rcvr.address(), members[i]->address());
+
+ // Wait for all signal messages, indicating the tokens have all reached zero.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ rcvr.wait();
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/bank_account_1.cpp b/3rdparty/asio/src/examples/cpp11/executors/bank_account_1.cpp
new file mode 100644
index 00000000000..85f7d9582af
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/bank_account_1.cpp
@@ -0,0 +1,54 @@
+#include <asio/post.hpp>
+#include <asio/thread_pool.hpp>
+#include <iostream>
+
+using asio::post;
+using asio::thread_pool;
+
+// Traditional active object pattern.
+// Member functions do not block.
+
+class bank_account
+{
+ int balance_ = 0;
+ mutable thread_pool pool_{1};
+
+public:
+ void deposit(int amount)
+ {
+ post(pool_, [=]
+ {
+ balance_ += amount;
+ });
+ }
+
+ void withdraw(int amount)
+ {
+ post(pool_, [=]
+ {
+ if (balance_ >= amount)
+ balance_ -= amount;
+ });
+ }
+
+ void print_balance() const
+ {
+ post(pool_, [=]
+ {
+ std::cout << "balance = " << balance_ << "\n";
+ });
+ }
+
+ ~bank_account()
+ {
+ pool_.join();
+ }
+};
+
+int main()
+{
+ bank_account acct;
+ acct.deposit(20);
+ acct.withdraw(10);
+ acct.print_balance();
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/bank_account_2.cpp b/3rdparty/asio/src/examples/cpp11/executors/bank_account_2.cpp
new file mode 100644
index 00000000000..b646cb29518
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/bank_account_2.cpp
@@ -0,0 +1,54 @@
+#include <asio/post.hpp>
+#include <asio/thread_pool.hpp>
+#include <asio/use_future.hpp>
+#include <iostream>
+
+using asio::post;
+using asio::thread_pool;
+using asio::use_future;
+
+// Traditional active object pattern.
+// Member functions block until operation is finished.
+
+class bank_account
+{
+ int balance_ = 0;
+ mutable thread_pool pool_{1};
+
+public:
+ void deposit(int amount)
+ {
+ post(pool_,
+ use_future([=]
+ {
+ balance_ += amount;
+ })).get();
+ }
+
+ void withdraw(int amount)
+ {
+ post(pool_,
+ use_future([=]
+ {
+ if (balance_ >= amount)
+ balance_ -= amount;
+ })).get();
+ }
+
+ int balance() const
+ {
+ return post(pool_,
+ use_future([=]
+ {
+ return balance_;
+ })).get();
+ }
+};
+
+int main()
+{
+ bank_account acct;
+ acct.deposit(20);
+ acct.withdraw(10);
+ std::cout << "balance = " << acct.balance() << "\n";
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/fork_join.cpp b/3rdparty/asio/src/examples/cpp11/executors/fork_join.cpp
new file mode 100644
index 00000000000..69716814823
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/fork_join.cpp
@@ -0,0 +1,327 @@
+#include <asio/dispatch.hpp>
+#include <asio/execution_context.hpp>
+#include <asio/thread_pool.hpp>
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+using asio::dispatch;
+using asio::execution_context;
+using asio::thread_pool;
+
+// A fixed-size thread pool used to implement fork/join semantics. Functions
+// are scheduled using a simple FIFO queue. Implementing work stealing, or
+// using a queue based on atomic operations, are left as tasks for the reader.
+class fork_join_pool : public execution_context
+{
+public:
+ // The constructor starts a thread pool with the specified number of threads.
+ // Note that the thread_count is not a fixed limit on the pool's concurrency.
+ // Additional threads may temporarily be added to the pool if they join a
+ // fork_executor.
+ explicit fork_join_pool(
+ std::size_t thread_count = std::thread::hardware_concurrency() * 2)
+ : use_count_(1),
+ threads_(thread_count)
+ {
+ try
+ {
+ // Ask each thread in the pool to dequeue and execute functions until
+ // it is time to shut down, i.e. the use count is zero.
+ for (thread_count_ = 0; thread_count_ < thread_count; ++thread_count_)
+ {
+ dispatch(threads_, [&]
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (use_count_ > 0)
+ if (!execute_next(lock))
+ condition_.wait(lock);
+ });
+ }
+ }
+ catch (...)
+ {
+ stop_threads();
+ threads_.join();
+ throw;
+ }
+ }
+
+ // The destructor waits for the pool to finish executing functions.
+ ~fork_join_pool()
+ {
+ stop_threads();
+ threads_.join();
+ }
+
+private:
+ friend class fork_executor;
+
+ // The base for all functions that are queued in the pool.
+ struct function_base
+ {
+ std::shared_ptr<std::size_t> work_count_;
+ void (*execute_)(std::shared_ptr<function_base>& p);
+ };
+
+ // Execute the next function from the queue, if any. Returns true if a
+ // function was executed, and false if the queue was empty.
+ bool execute_next(std::unique_lock<std::mutex>& lock)
+ {
+ if (queue_.empty())
+ return false;
+ auto p(queue_.front());
+ queue_.pop();
+ lock.unlock();
+ execute(lock, p);
+ return true;
+ }
+
+ // Execute a function and decrement the outstanding work.
+ void execute(std::unique_lock<std::mutex>& lock,
+ std::shared_ptr<function_base>& p)
+ {
+ std::shared_ptr<std::size_t> work_count(std::move(p->work_count_));
+ try
+ {
+ p->execute_(p);
+ lock.lock();
+ do_work_finished(work_count);
+ }
+ catch (...)
+ {
+ lock.lock();
+ do_work_finished(work_count);
+ throw;
+ }
+ }
+
+ // Increment outstanding work.
+ void do_work_started(const std::shared_ptr<std::size_t>& work_count) noexcept
+ {
+ if (++(*work_count) == 1)
+ ++use_count_;
+ }
+
+ // Decrement outstanding work. Notify waiting threads if we run out.
+ void do_work_finished(const std::shared_ptr<std::size_t>& work_count) noexcept
+ {
+ if (--(*work_count) == 0)
+ {
+ --use_count_;
+ condition_.notify_all();
+ }
+ }
+
+ // Dispatch a function, executing it immediately if the queue is already
+ // loaded. Otherwise adds the function to the queue and wakes a thread.
+ void do_dispatch(std::shared_ptr<function_base> p,
+ const std::shared_ptr<std::size_t>& work_count)
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ if (queue_.size() > thread_count_ * 16)
+ {
+ do_work_started(work_count);
+ lock.unlock();
+ execute(lock, p);
+ }
+ else
+ {
+ queue_.push(p);
+ do_work_started(work_count);
+ condition_.notify_one();
+ }
+ }
+
+ // Add a function to the queue and wake a thread.
+ void do_post(std::shared_ptr<function_base> p,
+ const std::shared_ptr<std::size_t>& work_count)
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push(p);
+ do_work_started(work_count);
+ condition_.notify_one();
+ }
+
+ // Ask all threads to shut down.
+ void stop_threads()
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ --use_count_;
+ condition_.notify_all();
+ }
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::queue<std::shared_ptr<function_base>> queue_;
+ std::size_t use_count_;
+ std::size_t thread_count_;
+ thread_pool threads_;
+};
+
+// A class that satisfies the Executor requirements. Every function or piece of
+// work associated with a fork_executor is part of a single, joinable group.
+class fork_executor
+{
+public:
+ fork_executor(fork_join_pool& ctx)
+ : context_(ctx),
+ work_count_(std::make_shared<std::size_t>(0))
+ {
+ }
+
+ fork_join_pool& context() const noexcept
+ {
+ return context_;
+ }
+
+ void on_work_started() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.do_work_started(work_count_);
+ }
+
+ void on_work_finished() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.do_work_finished(work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<function<Func>>(
+ typename std::allocator_traits<Alloc>::template rebind_alloc<char>(a),
+ std::move(f), work_count_));
+ context_.do_dispatch(p, work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<function<Func>>(
+ typename std::allocator_traits<Alloc>::template rebind_alloc<char>(a),
+ std::move(f), work_count_));
+ context_.do_post(p, work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const fork_executor& a,
+ const fork_executor& b) noexcept
+ {
+ return a.work_count_ == b.work_count_;
+ }
+
+ friend bool operator!=(const fork_executor& a,
+ const fork_executor& b) noexcept
+ {
+ return a.work_count_ != b.work_count_;
+ }
+
+ // Block until all work associated with the executor is complete. While it is
+ // waiting, the thread may be borrowed to execute functions from the queue.
+ void join() const
+ {
+ std::unique_lock<std::mutex> lock(context_.mutex_);
+ while (*work_count_ > 0)
+ if (!context_.execute_next(lock))
+ context_.condition_.wait(lock);
+ }
+
+private:
+ template <class Func>
+ struct function : fork_join_pool::function_base
+ {
+ explicit function(Func f, const std::shared_ptr<std::size_t>& w)
+ : function_(std::move(f))
+ {
+ work_count_ = w;
+ execute_ = [](std::shared_ptr<fork_join_pool::function_base>& p)
+ {
+ Func tmp(std::move(static_cast<function*>(p.get())->function_));
+ p.reset();
+ tmp();
+ };
+ }
+
+ Func function_;
+ };
+
+ fork_join_pool& context_;
+ std::shared_ptr<std::size_t> work_count_;
+};
+
+// Helper class to automatically join a fork_executor when exiting a scope.
+class join_guard
+{
+public:
+ explicit join_guard(const fork_executor& ex) : ex_(ex) {}
+ join_guard(const join_guard&) = delete;
+ join_guard(join_guard&&) = delete;
+ ~join_guard() { ex_.join(); }
+
+private:
+ fork_executor ex_;
+};
+
+//------------------------------------------------------------------------------
+
+#include <algorithm>
+#include <iostream>
+#include <random>
+#include <vector>
+
+fork_join_pool pool;
+
+template <class Iterator>
+void fork_join_sort(Iterator begin, Iterator end)
+{
+ std::size_t n = end - begin;
+ if (n > 32768)
+ {
+ {
+ fork_executor fork(pool);
+ join_guard join(fork);
+ dispatch(fork, [=]{ fork_join_sort(begin, begin + n / 2); });
+ dispatch(fork, [=]{ fork_join_sort(begin + n / 2, end); });
+ }
+ std::inplace_merge(begin, begin + n / 2, end);
+ }
+ else
+ {
+ std::sort(begin, end);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cerr << "Usage: fork_join <size>\n";
+ return 1;
+ }
+
+ std::vector<double> vec(std::atoll(argv[1]));
+ std::iota(vec.begin(), vec.end(), 0);
+
+ std::random_device rd;
+ std::mt19937 g(rd());
+ std::shuffle(vec.begin(), vec.end(), g);
+
+ std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
+
+ fork_join_sort(vec.begin(), vec.end());
+
+ std::chrono::steady_clock::duration elapsed = std::chrono::steady_clock::now() - start;
+
+ std::cout << "sort took ";
+ std::cout << std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
+ std::cout << " microseconds" << std::endl;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/pipeline.cpp b/3rdparty/asio/src/examples/cpp11/executors/pipeline.cpp
new file mode 100644
index 00000000000..86bf860cb9c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/pipeline.cpp
@@ -0,0 +1,298 @@
+#include <asio/associated_executor.hpp>
+#include <asio/bind_executor.hpp>
+#include <asio/execution_context.hpp>
+#include <asio/post.hpp>
+#include <asio/system_executor.hpp>
+#include <asio/use_future.hpp>
+#include <condition_variable>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+#include <vector>
+
+using asio::execution_context;
+using asio::executor_binder;
+using asio::get_associated_executor;
+using asio::post;
+using asio::system_executor;
+using asio::use_future;
+using asio::use_service;
+
+// An executor that launches a new thread for each function submitted to it.
+// This class satisfies the Executor requirements.
+class thread_executor
+{
+private:
+ // Service to track all threads started through a thread_executor.
+ class thread_bag : public execution_context::service
+ {
+ public:
+ typedef thread_bag key_type;
+
+ explicit thread_bag(execution_context& ctx)
+ : execution_context::service(ctx)
+ {
+ }
+
+ void add_thread(std::thread&& t)
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ threads_.push_back(std::move(t));
+ }
+
+ private:
+ virtual void shutdown()
+ {
+ for (auto& t : threads_)
+ t.join();
+ }
+
+ std::mutex mutex_;
+ std::vector<std::thread> threads_;
+ };
+
+public:
+ execution_context& context() const noexcept
+ {
+ return system_executor().context();
+ }
+
+ void on_work_started() const noexcept
+ {
+ // This executor doesn't count work.
+ }
+
+ void on_work_finished() const noexcept
+ {
+ // This executor doesn't count work.
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc&) const
+ {
+ thread_bag& bag = use_service<thread_bag>(context());
+ bag.add_thread(std::thread(std::move(f)));
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const thread_executor&,
+ const thread_executor&) noexcept
+ {
+ return true;
+ }
+
+ friend bool operator!=(const thread_executor&,
+ const thread_executor&) noexcept
+ {
+ return false;
+ }
+};
+
+// Base class for all thread-safe queue implementations.
+class queue_impl_base
+{
+ template <class> friend class queue_front;
+ template <class> friend class queue_back;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool stop_ = false;
+};
+
+// Underlying implementation of a thread-safe queue, shared between the
+// queue_front and queue_back classes.
+template <class T>
+class queue_impl : public queue_impl_base
+{
+ template <class> friend class queue_front;
+ template <class> friend class queue_back;
+ std::queue<T> queue_;
+};
+
+// The front end of a queue between consecutive pipeline stages.
+template <class T>
+class queue_front
+{
+public:
+ typedef T value_type;
+
+ explicit queue_front(std::shared_ptr<queue_impl<T>> impl)
+ : impl_(impl)
+ {
+ }
+
+ void push(T t)
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ impl_->queue_.push(std::move(t));
+ impl_->condition_.notify_one();
+ }
+
+ void stop()
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ impl_->stop_ = true;
+ impl_->condition_.notify_one();
+ }
+
+private:
+ std::shared_ptr<queue_impl<T>> impl_;
+};
+
+// The back end of a queue between consecutive pipeline stages.
+template <class T>
+class queue_back
+{
+public:
+ typedef T value_type;
+
+ explicit queue_back(std::shared_ptr<queue_impl<T>> impl)
+ : impl_(impl)
+ {
+ }
+
+ bool pop(T& t)
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ while (impl_->queue_.empty() && !impl_->stop_)
+ impl_->condition_.wait(lock);
+ if (!impl_->queue_.empty())
+ {
+ t = impl_->queue_.front();
+ impl_->queue_.pop();
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::shared_ptr<queue_impl<T>> impl_;
+};
+
+// Launch the last stage in a pipeline.
+template <class T, class F>
+std::future<void> pipeline(queue_back<T> in, F f)
+{
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function, and as we're the last stage return a future so that the
+ // caller can wait for the pipeline to finish.
+ return post(ex, use_future([in, f]() mutable { f(in); }));
+}
+
+// Launch an intermediate stage in a pipeline.
+template <class T, class F, class... Tail>
+std::future<void> pipeline(queue_back<T> in, F f, Tail... t)
+{
+ // Determine the output queue type.
+ typedef typename executor_binder<F, thread_executor>::second_argument_type::value_type output_value_type;
+
+ // Create the output queue and its implementation.
+ auto out_impl = std::make_shared<queue_impl<output_value_type>>();
+ queue_front<output_value_type> out(out_impl);
+ queue_back<output_value_type> next_in(out_impl);
+
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function.
+ post(ex, [in, out, f]() mutable
+ {
+ f(in, out);
+ out.stop();
+ });
+
+ // Launch the rest of the pipeline.
+ return pipeline(next_in, std::move(t)...);
+}
+
+// Launch the first stage in a pipeline.
+template <class F, class... Tail>
+std::future<void> pipeline(F f, Tail... t)
+{
+ // Determine the output queue type.
+ typedef typename executor_binder<F, thread_executor>::argument_type::value_type output_value_type;
+
+ // Create the output queue and its implementation.
+ auto out_impl = std::make_shared<queue_impl<output_value_type>>();
+ queue_front<output_value_type> out(out_impl);
+ queue_back<output_value_type> next_in(out_impl);
+
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function.
+ post(ex, [out, f]() mutable
+ {
+ f(out);
+ out.stop();
+ });
+
+ // Launch the rest of the pipeline.
+ return pipeline(next_in, std::move(t)...);
+}
+
+//------------------------------------------------------------------------------
+
+#include <asio/thread_pool.hpp>
+#include <iostream>
+#include <string>
+
+using asio::bind_executor;
+using asio::thread_pool;
+
+void reader(queue_front<std::string> out)
+{
+ std::string line;
+ while (std::getline(std::cin, line))
+ out.push(line);
+}
+
+void filter(queue_back<std::string> in, queue_front<std::string> out)
+{
+ std::string line;
+ while (in.pop(line))
+ if (line.length() > 5)
+ out.push(line);
+}
+
+void upper(queue_back<std::string> in, queue_front<std::string> out)
+{
+ std::string line;
+ while (in.pop(line))
+ {
+ std::string new_line;
+ for (char c : line)
+ new_line.push_back(std::toupper(c));
+ out.push(new_line);
+ }
+}
+
+void writer(queue_back<std::string> in)
+{
+ std::size_t count = 0;
+ std::string line;
+ while (in.pop(line))
+ std::cout << count++ << ": " << line << std::endl;
+}
+
+int main()
+{
+ thread_pool pool;
+
+ auto f = pipeline(reader, filter, bind_executor(pool, upper), writer);
+ f.wait();
+}
diff --git a/3rdparty/asio/src/examples/cpp11/executors/priority_scheduler.cpp b/3rdparty/asio/src/examples/cpp11/executors/priority_scheduler.cpp
new file mode 100644
index 00000000000..fb38fa2ce4b
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/executors/priority_scheduler.cpp
@@ -0,0 +1,168 @@
+#include <asio/dispatch.hpp>
+#include <asio/execution_context.hpp>
+#include <condition_variable>
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <queue>
+
+using asio::dispatch;
+using asio::execution_context;
+
+class priority_scheduler : public execution_context
+{
+public:
+ // A class that satisfies the Executor requirements.
+ class executor_type
+ {
+ public:
+ executor_type(priority_scheduler& ctx, int pri) noexcept
+ : context_(ctx), priority_(pri)
+ {
+ }
+
+ priority_scheduler& context() const noexcept
+ {
+ return context_;
+ }
+
+ void on_work_started() const noexcept
+ {
+ // This executor doesn't count work. Instead, the scheduler simply runs
+ // until explicitly stopped.
+ }
+
+ void on_work_finished() const noexcept
+ {
+ // This executor doesn't count work. Instead, the scheduler simply runs
+ // until explicitly stopped.
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<item<Func>>(
+ typename std::allocator_traits<
+ Alloc>::template rebind_alloc<char>(a),
+ priority_, std::move(f)));
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.queue_.push(p);
+ context_.condition_.notify_one();
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const executor_type& a,
+ const executor_type& b) noexcept
+ {
+ return &a.context_ == &b.context_;
+ }
+
+ friend bool operator!=(const executor_type& a,
+ const executor_type& b) noexcept
+ {
+ return &a.context_ != &b.context_;
+ }
+
+ private:
+ priority_scheduler& context_;
+ int priority_;
+ };
+
+ executor_type get_executor(int pri = 0) noexcept
+ {
+ return executor_type(*const_cast<priority_scheduler*>(this), pri);
+ }
+
+ void run()
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ for (;;)
+ {
+ condition_.wait(lock, [&]{ return stopped_ || !queue_.empty(); });
+ if (stopped_)
+ return;
+ auto p(queue_.top());
+ queue_.pop();
+ lock.unlock();
+ p->execute_(p);
+ lock.lock();
+ }
+ }
+
+ void stop()
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ stopped_ = true;
+ condition_.notify_all();
+ }
+
+private:
+ struct item_base
+ {
+ int priority_;
+ void (*execute_)(std::shared_ptr<item_base>&);
+ };
+
+ template <class Func>
+ struct item : item_base
+ {
+ item(int pri, Func f) : function_(std::move(f))
+ {
+ priority_ = pri;
+ execute_ = [](std::shared_ptr<item_base>& p)
+ {
+ Func tmp(std::move(static_cast<item*>(p.get())->function_));
+ p.reset();
+ tmp();
+ };
+ }
+
+ Func function_;
+ };
+
+ struct item_comp
+ {
+ bool operator()(
+ const std::shared_ptr<item_base>& a,
+ const std::shared_ptr<item_base>& b)
+ {
+ return a->priority_ < b->priority_;
+ }
+ };
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::priority_queue<
+ std::shared_ptr<item_base>,
+ std::vector<std::shared_ptr<item_base>>,
+ item_comp> queue_;
+ bool stopped_ = false;
+};
+
+int main()
+{
+ priority_scheduler sched;
+ auto low = sched.get_executor(0);
+ auto med = sched.get_executor(1);
+ auto high = sched.get_executor(2);
+ dispatch(low, []{ std::cout << "1\n"; });
+ dispatch(low, []{ std::cout << "11\n"; });
+ dispatch(med, []{ std::cout << "2\n"; });
+ dispatch(med, []{ std::cout << "22\n"; });
+ dispatch(high, []{ std::cout << "3\n"; });
+ dispatch(high, []{ std::cout << "33\n"; });
+ dispatch(high, []{ std::cout << "333\n"; });
+ dispatch(sched.get_executor(-1), [&]{ sched.stop(); });
+ sched.run();
+}
diff --git a/3rdparty/asio/src/examples/cpp11/futures/.gitignore b/3rdparty/asio/src/examples/cpp11/futures/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/futures/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/futures/daytime_client.cpp b/3rdparty/asio/src/examples/cpp11/futures/daytime_client.cpp
new file mode 100644
index 00000000000..0004e124ff6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/futures/daytime_client.cpp
@@ -0,0 +1,94 @@
+//
+// daytime_client.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <array>
+#include <future>
+#include <iostream>
+#include <thread>
+#include <asio/io_context.hpp>
+#include <asio/ip/udp.hpp>
+#include <asio/use_future.hpp>
+
+using asio::ip::udp;
+
+void get_daytime(asio::io_context& io_context, const char* hostname)
+{
+ try
+ {
+ udp::resolver resolver(io_context);
+
+ std::future<udp::resolver::results_type> endpoints =
+ resolver.async_resolve(
+ udp::v4(), hostname, "daytime",
+ asio::use_future);
+
+ // The async_resolve operation above returns the endpoints as a future
+ // value that is not retrieved ...
+
+ udp::socket socket(io_context, udp::v4());
+
+ std::array<char, 1> send_buf = {{ 0 }};
+ std::future<std::size_t> send_length =
+ socket.async_send_to(asio::buffer(send_buf),
+ *endpoints.get().begin(), // ... until here. This call may block.
+ asio::use_future);
+
+ // Do other things here while the send completes.
+
+ send_length.get(); // Blocks until the send is complete. Throws any errors.
+
+ std::array<char, 128> recv_buf;
+ udp::endpoint sender_endpoint;
+ std::future<std::size_t> recv_length =
+ socket.async_receive_from(
+ asio::buffer(recv_buf),
+ sender_endpoint,
+ asio::use_future);
+
+ // Do other things here while the receive completes.
+
+ std::cout.write(
+ recv_buf.data(),
+ recv_length.get()); // Blocks until receive is complete.
+ }
+ catch (std::system_error& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: daytime_client <host>" << std::endl;
+ return 1;
+ }
+
+ // We run the io_context off in its own thread so that it operates
+ // completely asynchronously with respect to the rest of the program.
+ asio::io_context io_context;
+ auto work = asio::make_work_guard(io_context);
+ std::thread thread([&io_context](){ io_context.run(); });
+
+ get_daytime(io_context, argv[1]);
+
+ io_context.stop();
+ thread.join();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp b/3rdparty/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp
new file mode 100644
index 00000000000..41b355c748c
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp
@@ -0,0 +1,201 @@
+//
+// custom_tracking.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 CUSTOM_TRACKING_HPP
+#define CUSTOM_TRACKING_HPP
+
+#include <cinttypes>
+#include <cstdint>
+#include <cstdio>
+
+# define ASIO_INHERIT_TRACKED_HANDLER \
+ : public ::custom_tracking::tracked_handler
+
+# define ASIO_ALSO_INHERIT_TRACKED_HANDLER \
+ , public ::custom_tracking::tracked_handler
+
+# define ASIO_HANDLER_TRACKING_INIT \
+ ::custom_tracking::init()
+
+# define ASIO_HANDLER_CREATION(args) \
+ ::custom_tracking::creation args
+
+# define ASIO_HANDLER_COMPLETION(args) \
+ ::custom_tracking::completion tracked_completion args
+
+# define ASIO_HANDLER_INVOCATION_BEGIN(args) \
+ tracked_completion.invocation_begin args
+
+# define ASIO_HANDLER_INVOCATION_END \
+ tracked_completion.invocation_end()
+
+# define ASIO_HANDLER_OPERATION(args) \
+ ::custom_tracking::operation args
+
+# define ASIO_HANDLER_REACTOR_REGISTRATION(args) \
+ ::custom_tracking::reactor_registration args
+
+# define ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \
+ ::custom_tracking::reactor_deregistration args
+
+# define ASIO_HANDLER_REACTOR_READ_EVENT 1
+# define ASIO_HANDLER_REACTOR_WRITE_EVENT 2
+# define ASIO_HANDLER_REACTOR_ERROR_EVENT 4
+
+# define ASIO_HANDLER_REACTOR_EVENTS(args) \
+ ::custom_tracking::reactor_events args
+
+# define ASIO_HANDLER_REACTOR_OPERATION(args) \
+ ::custom_tracking::reactor_operation args
+
+struct custom_tracking
+{
+ // Base class for objects containing tracked handlers.
+ struct tracked_handler
+ {
+ std::uintmax_t handler_id_ = 0; // To uniquely identify a handler.
+ std::uintmax_t tree_id_ = 0; // To identify related handlers.
+ const char* object_type_; // The object type associated with the handler.
+ std::uintmax_t native_handle_; // Native handle, if any.
+ };
+
+ // Initialise the tracking system.
+ static void init()
+ {
+ }
+
+ // Record the creation of a tracked handler.
+ static void creation(asio::execution_context& /*ctx*/, tracked_handler& h,
+ const char* object_type, void* /*object*/,
+ std::uintmax_t native_handle, const char* op_name)
+ {
+ // Generate a unique id for the new handler.
+ static std::atomic<std::uintmax_t> next_handler_id{1};
+ h.handler_id_ = next_handler_id++;
+
+ // Copy the tree identifier forward from the current handler.
+ if (*current_completion())
+ h.tree_id_ = (*current_completion())->handler_.tree_id_;
+
+ // Store various attributes of the operation to use in later output.
+ h.object_type_ = object_type;
+ h.native_handle_ = native_handle;
+
+ std::printf(
+ "Starting operation %s.%s for native_handle = %" PRIuMAX
+ ", handler = %" PRIuMAX ", tree = %" PRIuMAX "\n",
+ object_type, op_name, h.native_handle_, h.handler_id_, h.tree_id_);
+ }
+
+ struct completion
+ {
+ explicit completion(const tracked_handler& h)
+ : handler_(h),
+ next_(*current_completion())
+ {
+ *current_completion() = this;
+ }
+
+ completion(const completion&) = delete;
+ completion& operator=(const completion&) = delete;
+
+ // Destructor records only when an exception is thrown from the handler, or
+ // if the memory is being freed without the handler having been invoked.
+ ~completion()
+ {
+ *current_completion() = next_;
+ }
+
+ // Records that handler is to be invoked with the specified arguments.
+ template <class... Args>
+ void invocation_begin(Args&&... /*args*/)
+ {
+ std::printf("Entering handler %" PRIuMAX " in tree %" PRIuMAX "\n",
+ handler_.handler_id_, handler_.tree_id_);
+ }
+
+ // Record that handler invocation has ended.
+ void invocation_end()
+ {
+ std::printf("Leaving handler %" PRIuMAX " in tree %" PRIuMAX "\n",
+ handler_.handler_id_, handler_.tree_id_);
+ }
+
+ tracked_handler handler_;
+
+ // Completions may nest. Here we stash a pointer to the outer completion.
+ completion* next_;
+ };
+
+ static completion** current_completion()
+ {
+ static ASIO_THREAD_KEYWORD completion* current = nullptr;
+ return &current;
+ }
+
+ // Record an operation that is not directly associated with a handler.
+ static void operation(asio::execution_context& /*ctx*/,
+ const char* /*object_type*/, void* /*object*/,
+ std::uintmax_t /*native_handle*/, const char* /*op_name*/)
+ {
+ }
+
+ // Record that a descriptor has been registered with the reactor.
+ static void reactor_registration(asio::execution_context& context,
+ uintmax_t native_handle, uintmax_t registration)
+ {
+ std::printf("Adding to reactor native_handle = %" PRIuMAX
+ ", registration = %" PRIuMAX "\n", native_handle, registration);
+ }
+
+ // Record that a descriptor has been deregistered from the reactor.
+ static void reactor_deregistration(asio::execution_context& context,
+ uintmax_t native_handle, uintmax_t registration)
+ {
+ std::printf("Removing from reactor native_handle = %" PRIuMAX
+ ", registration = %" PRIuMAX "\n", native_handle, registration);
+ }
+
+ // Record reactor-based readiness events associated with a descriptor.
+ static void reactor_events(asio::execution_context& context,
+ uintmax_t registration, unsigned events)
+ {
+ std::printf(
+ "Reactor readiness for registration = %" PRIuMAX ", events =%s%s%s\n",
+ registration,
+ (events & ASIO_HANDLER_REACTOR_READ_EVENT) ? " read" : "",
+ (events & ASIO_HANDLER_REACTOR_WRITE_EVENT) ? " write" : "",
+ (events & ASIO_HANDLER_REACTOR_ERROR_EVENT) ? " error" : "");
+ }
+
+ // Record a reactor-based operation that is associated with a handler.
+ static void reactor_operation(const tracked_handler& h,
+ const char* op_name, const asio::error_code& ec)
+ {
+ std::printf(
+ "Performed operation %s.%s for native_handle = %" PRIuMAX
+ ", ec = %s:%d\n", h.object_type_, op_name, h.native_handle_,
+ ec.category().name(), ec.value());
+ }
+
+ // Record a reactor-based operation that is associated with a handler.
+ static void reactor_operation(const tracked_handler& h,
+ const char* op_name, const asio::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ std::printf(
+ "Performed operation %s.%s for native_handle = %" PRIuMAX
+ ", ec = %s:%d, n = %" PRIuMAX "\n", h.object_type_, op_name,
+ h.native_handle_, ec.category().name(), ec.value(),
+ static_cast<uintmax_t>(bytes_transferred));
+ }
+};
+
+#endif // CUSTOM_TRACKING_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/.gitignore b/3rdparty/asio/src/examples/cpp11/http/server/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp b/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp
new file mode 100644
index 00000000000..f4d9cac46e5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp
@@ -0,0 +1,94 @@
+//
+// connection.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection.hpp"
+#include <utility>
+#include <vector>
+#include "connection_manager.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server {
+
+connection::connection(asio::ip::tcp::socket socket,
+ connection_manager& manager, request_handler& handler)
+ : socket_(std::move(socket)),
+ connection_manager_(manager),
+ request_handler_(handler)
+{
+}
+
+void connection::start()
+{
+ do_read();
+}
+
+void connection::stop()
+{
+ socket_.close();
+}
+
+void connection::do_read()
+{
+ auto self(shared_from_this());
+ socket_.async_read_some(asio::buffer(buffer_),
+ [this, self](std::error_code ec, std::size_t bytes_transferred)
+ {
+ if (!ec)
+ {
+ request_parser::result_type result;
+ std::tie(result, std::ignore) = request_parser_.parse(
+ request_, buffer_.data(), buffer_.data() + bytes_transferred);
+
+ if (result == request_parser::good)
+ {
+ request_handler_.handle_request(request_, reply_);
+ do_write();
+ }
+ else if (result == request_parser::bad)
+ {
+ reply_ = reply::stock_reply(reply::bad_request);
+ do_write();
+ }
+ else
+ {
+ do_read();
+ }
+ }
+ else if (ec != asio::error::operation_aborted)
+ {
+ connection_manager_.stop(shared_from_this());
+ }
+ });
+}
+
+void connection::do_write()
+{
+ auto self(shared_from_this());
+ asio::async_write(socket_, reply_.to_buffers(),
+ [this, self](std::error_code ec, std::size_t)
+ {
+ if (!ec)
+ {
+ // Initiate graceful connection closure.
+ asio::error_code ignored_ec;
+ socket_.shutdown(asio::ip::tcp::socket::shutdown_both,
+ ignored_ec);
+ }
+
+ if (ec != asio::error::operation_aborted)
+ {
+ connection_manager_.stop(shared_from_this());
+ }
+ });
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/connection.hpp b/3rdparty/asio/src/examples/cpp11/http/server/connection.hpp
new file mode 100644
index 00000000000..96364db0daa
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/connection.hpp
@@ -0,0 +1,79 @@
+//
+// connection.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_CONNECTION_HPP
+#define HTTP_CONNECTION_HPP
+
+#include <array>
+#include <memory>
+#include <asio.hpp>
+#include "reply.hpp"
+#include "request.hpp"
+#include "request_handler.hpp"
+#include "request_parser.hpp"
+
+namespace http {
+namespace server {
+
+class connection_manager;
+
+/// Represents a single connection from a client.
+class connection
+ : public std::enable_shared_from_this<connection>
+{
+public:
+ connection(const connection&) = delete;
+ connection& operator=(const connection&) = delete;
+
+ /// Construct a connection with the given socket.
+ explicit connection(asio::ip::tcp::socket socket,
+ connection_manager& manager, request_handler& handler);
+
+ /// Start the first asynchronous operation for the connection.
+ void start();
+
+ /// Stop all asynchronous operations associated with the connection.
+ void stop();
+
+private:
+ /// Perform an asynchronous read operation.
+ void do_read();
+
+ /// Perform an asynchronous write operation.
+ void do_write();
+
+ /// Socket for the connection.
+ asio::ip::tcp::socket socket_;
+
+ /// The manager for this connection.
+ connection_manager& connection_manager_;
+
+ /// The handler used to process the incoming request.
+ request_handler& request_handler_;
+
+ /// Buffer for incoming data.
+ std::array<char, 8192> buffer_;
+
+ /// The incoming request.
+ request request_;
+
+ /// The parser for the incoming request.
+ request_parser request_parser_;
+
+ /// The reply to be sent back to the client.
+ reply reply_;
+};
+
+typedef std::shared_ptr<connection> connection_ptr;
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_CONNECTION_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.cpp b/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.cpp
new file mode 100644
index 00000000000..55bfb9ad719
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.cpp
@@ -0,0 +1,40 @@
+//
+// connection_manager.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "connection_manager.hpp"
+
+namespace http {
+namespace server {
+
+connection_manager::connection_manager()
+{
+}
+
+void connection_manager::start(connection_ptr c)
+{
+ connections_.insert(c);
+ c->start();
+}
+
+void connection_manager::stop(connection_ptr c)
+{
+ connections_.erase(c);
+ c->stop();
+}
+
+void connection_manager::stop_all()
+{
+ for (auto c: connections_)
+ c->stop();
+ connections_.clear();
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.hpp b/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.hpp
new file mode 100644
index 00000000000..8dadf416347
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/connection_manager.hpp
@@ -0,0 +1,48 @@
+//
+// connection_manager.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_CONNECTION_MANAGER_HPP
+#define HTTP_CONNECTION_MANAGER_HPP
+
+#include <set>
+#include "connection.hpp"
+
+namespace http {
+namespace server {
+
+/// Manages open connections so that they may be cleanly stopped when the server
+/// needs to shut down.
+class connection_manager
+{
+public:
+ connection_manager(const connection_manager&) = delete;
+ connection_manager& operator=(const connection_manager&) = delete;
+
+ /// Construct a connection manager.
+ connection_manager();
+
+ /// Add the specified connection to the manager and start it.
+ void start(connection_ptr c);
+
+ /// Stop the specified connection.
+ void stop(connection_ptr c);
+
+ /// Stop all connections.
+ void stop_all();
+
+private:
+ /// The managed connections.
+ std::set<connection_ptr> connections_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_CONNECTION_MANAGER_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/header.hpp b/3rdparty/asio/src/examples/cpp11/http/server/header.hpp
new file mode 100644
index 00000000000..22e3c4a7a10
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/header.hpp
@@ -0,0 +1,28 @@
+//
+// header.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_HEADER_HPP
+#define HTTP_HEADER_HPP
+
+#include <string>
+
+namespace http {
+namespace server {
+
+struct header
+{
+ std::string name;
+ std::string value;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_HEADER_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/main.cpp b/3rdparty/asio/src/examples/cpp11/http/server/main.cpp
new file mode 100644
index 00000000000..44fc930f494
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/main.cpp
@@ -0,0 +1,43 @@
+//
+// main.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <string>
+#include <asio.hpp>
+#include "server.hpp"
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ // Check command line arguments.
+ if (argc != 4)
+ {
+ std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
+ std::cerr << " For IPv4, try:\n";
+ std::cerr << " receiver 0.0.0.0 80 .\n";
+ std::cerr << " For IPv6, try:\n";
+ std::cerr << " receiver 0::0 80 .\n";
+ return 1;
+ }
+
+ // Initialise the server.
+ http::server::server s(argv[1], argv[2], argv[3]);
+
+ // Run the server until stopped.
+ s.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/mime_types.cpp b/3rdparty/asio/src/examples/cpp11/http/server/mime_types.cpp
new file mode 100644
index 00000000000..eb779197189
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/mime_types.cpp
@@ -0,0 +1,45 @@
+//
+// mime_types.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "mime_types.hpp"
+
+namespace http {
+namespace server {
+namespace mime_types {
+
+struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "gif", "image/gif" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "jpg", "image/jpeg" },
+ { "png", "image/png" }
+};
+
+std::string extension_to_type(const std::string& extension)
+{
+ for (mapping m: mappings)
+ {
+ if (m.extension == extension)
+ {
+ return m.mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+} // namespace mime_types
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/mime_types.hpp b/3rdparty/asio/src/examples/cpp11/http/server/mime_types.hpp
new file mode 100644
index 00000000000..2fc0332791f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/mime_types.hpp
@@ -0,0 +1,27 @@
+//
+// mime_types.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_MIME_TYPES_HPP
+#define HTTP_MIME_TYPES_HPP
+
+#include <string>
+
+namespace http {
+namespace server {
+namespace mime_types {
+
+/// Convert a file extension into a MIME type.
+std::string extension_to_type(const std::string& extension);
+
+} // namespace mime_types
+} // namespace server
+} // namespace http
+
+#endif // HTTP_MIME_TYPES_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/reply.cpp b/3rdparty/asio/src/examples/cpp11/http/server/reply.cpp
new file mode 100644
index 00000000000..2c9901312bb
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/reply.cpp
@@ -0,0 +1,255 @@
+//
+// reply.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "reply.hpp"
+#include <string>
+
+namespace http {
+namespace server {
+
+namespace status_strings {
+
+const std::string ok =
+ "HTTP/1.0 200 OK\r\n";
+const std::string created =
+ "HTTP/1.0 201 Created\r\n";
+const std::string accepted =
+ "HTTP/1.0 202 Accepted\r\n";
+const std::string no_content =
+ "HTTP/1.0 204 No Content\r\n";
+const std::string multiple_choices =
+ "HTTP/1.0 300 Multiple Choices\r\n";
+const std::string moved_permanently =
+ "HTTP/1.0 301 Moved Permanently\r\n";
+const std::string moved_temporarily =
+ "HTTP/1.0 302 Moved Temporarily\r\n";
+const std::string not_modified =
+ "HTTP/1.0 304 Not Modified\r\n";
+const std::string bad_request =
+ "HTTP/1.0 400 Bad Request\r\n";
+const std::string unauthorized =
+ "HTTP/1.0 401 Unauthorized\r\n";
+const std::string forbidden =
+ "HTTP/1.0 403 Forbidden\r\n";
+const std::string not_found =
+ "HTTP/1.0 404 Not Found\r\n";
+const std::string internal_server_error =
+ "HTTP/1.0 500 Internal Server Error\r\n";
+const std::string not_implemented =
+ "HTTP/1.0 501 Not Implemented\r\n";
+const std::string bad_gateway =
+ "HTTP/1.0 502 Bad Gateway\r\n";
+const std::string service_unavailable =
+ "HTTP/1.0 503 Service Unavailable\r\n";
+
+asio::const_buffer to_buffer(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return asio::buffer(ok);
+ case reply::created:
+ return asio::buffer(created);
+ case reply::accepted:
+ return asio::buffer(accepted);
+ case reply::no_content:
+ return asio::buffer(no_content);
+ case reply::multiple_choices:
+ return asio::buffer(multiple_choices);
+ case reply::moved_permanently:
+ return asio::buffer(moved_permanently);
+ case reply::moved_temporarily:
+ return asio::buffer(moved_temporarily);
+ case reply::not_modified:
+ return asio::buffer(not_modified);
+ case reply::bad_request:
+ return asio::buffer(bad_request);
+ case reply::unauthorized:
+ return asio::buffer(unauthorized);
+ case reply::forbidden:
+ return asio::buffer(forbidden);
+ case reply::not_found:
+ return asio::buffer(not_found);
+ case reply::internal_server_error:
+ return asio::buffer(internal_server_error);
+ case reply::not_implemented:
+ return asio::buffer(not_implemented);
+ case reply::bad_gateway:
+ return asio::buffer(bad_gateway);
+ case reply::service_unavailable:
+ return asio::buffer(service_unavailable);
+ default:
+ return asio::buffer(internal_server_error);
+ }
+}
+
+} // namespace status_strings
+
+namespace misc_strings {
+
+const char name_value_separator[] = { ':', ' ' };
+const char crlf[] = { '\r', '\n' };
+
+} // namespace misc_strings
+
+std::vector<asio::const_buffer> reply::to_buffers()
+{
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(status_strings::to_buffer(status));
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ header& h = headers[i];
+ buffers.push_back(asio::buffer(h.name));
+ buffers.push_back(asio::buffer(misc_strings::name_value_separator));
+ buffers.push_back(asio::buffer(h.value));
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ }
+ buffers.push_back(asio::buffer(misc_strings::crlf));
+ buffers.push_back(asio::buffer(content));
+ return buffers;
+}
+
+namespace stock_replies {
+
+const char ok[] = "";
+const char created[] =
+ "<html>"
+ "<head><title>Created</title></head>"
+ "<body><h1>201 Created</h1></body>"
+ "</html>";
+const char accepted[] =
+ "<html>"
+ "<head><title>Accepted</title></head>"
+ "<body><h1>202 Accepted</h1></body>"
+ "</html>";
+const char no_content[] =
+ "<html>"
+ "<head><title>No Content</title></head>"
+ "<body><h1>204 Content</h1></body>"
+ "</html>";
+const char multiple_choices[] =
+ "<html>"
+ "<head><title>Multiple Choices</title></head>"
+ "<body><h1>300 Multiple Choices</h1></body>"
+ "</html>";
+const char moved_permanently[] =
+ "<html>"
+ "<head><title>Moved Permanently</title></head>"
+ "<body><h1>301 Moved Permanently</h1></body>"
+ "</html>";
+const char moved_temporarily[] =
+ "<html>"
+ "<head><title>Moved Temporarily</title></head>"
+ "<body><h1>302 Moved Temporarily</h1></body>"
+ "</html>";
+const char not_modified[] =
+ "<html>"
+ "<head><title>Not Modified</title></head>"
+ "<body><h1>304 Not Modified</h1></body>"
+ "</html>";
+const char bad_request[] =
+ "<html>"
+ "<head><title>Bad Request</title></head>"
+ "<body><h1>400 Bad Request</h1></body>"
+ "</html>";
+const char unauthorized[] =
+ "<html>"
+ "<head><title>Unauthorized</title></head>"
+ "<body><h1>401 Unauthorized</h1></body>"
+ "</html>";
+const char forbidden[] =
+ "<html>"
+ "<head><title>Forbidden</title></head>"
+ "<body><h1>403 Forbidden</h1></body>"
+ "</html>";
+const char not_found[] =
+ "<html>"
+ "<head><title>Not Found</title></head>"
+ "<body><h1>404 Not Found</h1></body>"
+ "</html>";
+const char internal_server_error[] =
+ "<html>"
+ "<head><title>Internal Server Error</title></head>"
+ "<body><h1>500 Internal Server Error</h1></body>"
+ "</html>";
+const char not_implemented[] =
+ "<html>"
+ "<head><title>Not Implemented</title></head>"
+ "<body><h1>501 Not Implemented</h1></body>"
+ "</html>";
+const char bad_gateway[] =
+ "<html>"
+ "<head><title>Bad Gateway</title></head>"
+ "<body><h1>502 Bad Gateway</h1></body>"
+ "</html>";
+const char service_unavailable[] =
+ "<html>"
+ "<head><title>Service Unavailable</title></head>"
+ "<body><h1>503 Service Unavailable</h1></body>"
+ "</html>";
+
+std::string to_string(reply::status_type status)
+{
+ switch (status)
+ {
+ case reply::ok:
+ return ok;
+ case reply::created:
+ return created;
+ case reply::accepted:
+ return accepted;
+ case reply::no_content:
+ return no_content;
+ case reply::multiple_choices:
+ return multiple_choices;
+ case reply::moved_permanently:
+ return moved_permanently;
+ case reply::moved_temporarily:
+ return moved_temporarily;
+ case reply::not_modified:
+ return not_modified;
+ case reply::bad_request:
+ return bad_request;
+ case reply::unauthorized:
+ return unauthorized;
+ case reply::forbidden:
+ return forbidden;
+ case reply::not_found:
+ return not_found;
+ case reply::internal_server_error:
+ return internal_server_error;
+ case reply::not_implemented:
+ return not_implemented;
+ case reply::bad_gateway:
+ return bad_gateway;
+ case reply::service_unavailable:
+ return service_unavailable;
+ default:
+ return internal_server_error;
+ }
+}
+
+} // namespace stock_replies
+
+reply reply::stock_reply(reply::status_type status)
+{
+ reply rep;
+ rep.status = status;
+ rep.content = stock_replies::to_string(status);
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = std::to_string(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = "text/html";
+ return rep;
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/reply.hpp b/3rdparty/asio/src/examples/cpp11/http/server/reply.hpp
new file mode 100644
index 00000000000..5189ac4363e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/reply.hpp
@@ -0,0 +1,64 @@
+//
+// reply.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REPLY_HPP
+#define HTTP_REPLY_HPP
+
+#include <string>
+#include <vector>
+#include <asio.hpp>
+#include "header.hpp"
+
+namespace http {
+namespace server {
+
+/// A reply to be sent to a client.
+struct reply
+{
+ /// The status of the reply.
+ enum status_type
+ {
+ ok = 200,
+ created = 201,
+ accepted = 202,
+ no_content = 204,
+ multiple_choices = 300,
+ moved_permanently = 301,
+ moved_temporarily = 302,
+ not_modified = 304,
+ bad_request = 400,
+ unauthorized = 401,
+ forbidden = 403,
+ not_found = 404,
+ internal_server_error = 500,
+ not_implemented = 501,
+ bad_gateway = 502,
+ service_unavailable = 503
+ } status;
+
+ /// The headers to be included in the reply.
+ std::vector<header> headers;
+
+ /// The content to be sent in the reply.
+ std::string content;
+
+ /// Convert the reply into a vector of buffers. The buffers do not own the
+ /// underlying memory blocks, therefore the reply object must remain valid and
+ /// not be changed until the write operation has completed.
+ std::vector<asio::const_buffer> to_buffers();
+
+ /// Get a stock reply.
+ static reply stock_reply(status_type status);
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REPLY_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/request.hpp b/3rdparty/asio/src/examples/cpp11/http/server/request.hpp
new file mode 100644
index 00000000000..129a3990b3d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/request.hpp
@@ -0,0 +1,34 @@
+//
+// request.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_HPP
+#define HTTP_REQUEST_HPP
+
+#include <string>
+#include <vector>
+#include "header.hpp"
+
+namespace http {
+namespace server {
+
+/// A request received from a client.
+struct request
+{
+ std::string method;
+ std::string uri;
+ int http_version_major;
+ int http_version_minor;
+ std::vector<header> headers;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/request_handler.cpp b/3rdparty/asio/src/examples/cpp11/http/server/request_handler.cpp
new file mode 100644
index 00000000000..c346ab9791e
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/request_handler.cpp
@@ -0,0 +1,121 @@
+//
+// request_handler.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_handler.hpp"
+#include <fstream>
+#include <sstream>
+#include <string>
+#include "mime_types.hpp"
+#include "reply.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server {
+
+request_handler::request_handler(const std::string& doc_root)
+ : doc_root_(doc_root)
+{
+}
+
+void request_handler::handle_request(const request& req, reply& rep)
+{
+ // Decode url to path.
+ std::string request_path;
+ if (!url_decode(req.uri, request_path))
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // Request path must be absolute and not contain "..".
+ if (request_path.empty() || request_path[0] != '/'
+ || request_path.find("..") != std::string::npos)
+ {
+ rep = reply::stock_reply(reply::bad_request);
+ return;
+ }
+
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (request_path[request_path.size() - 1] == '/')
+ {
+ request_path += "index.html";
+ }
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = request_path.find_last_of("/");
+ std::size_t last_dot_pos = request_path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = request_path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root_ + request_path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ rep = reply::stock_reply(reply::not_found);
+ return;
+ }
+
+ // Fill out the reply to be sent to the client.
+ rep.status = reply::ok;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ rep.content.append(buf, is.gcount());
+ rep.headers.resize(2);
+ rep.headers[0].name = "Content-Length";
+ rep.headers[0].value = std::to_string(rep.content.size());
+ rep.headers[1].name = "Content-Type";
+ rep.headers[1].value = mime_types::extension_to_type(extension);
+}
+
+bool request_handler::url_decode(const std::string& in, std::string& out)
+{
+ out.clear();
+ out.reserve(in.size());
+ for (std::size_t i = 0; i < in.size(); ++i)
+ {
+ if (in[i] == '%')
+ {
+ if (i + 3 <= in.size())
+ {
+ int value = 0;
+ std::istringstream is(in.substr(i + 1, 2));
+ if (is >> std::hex >> value)
+ {
+ out += static_cast<char>(value);
+ i += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (in[i] == '+')
+ {
+ out += ' ';
+ }
+ else
+ {
+ out += in[i];
+ }
+ }
+ return true;
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/request_handler.hpp b/3rdparty/asio/src/examples/cpp11/http/server/request_handler.hpp
new file mode 100644
index 00000000000..24cca33565a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/request_handler.hpp
@@ -0,0 +1,47 @@
+//
+// request_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_HANDLER_HPP
+#define HTTP_REQUEST_HANDLER_HPP
+
+#include <string>
+
+namespace http {
+namespace server {
+
+struct reply;
+struct request;
+
+/// The common handler for all incoming requests.
+class request_handler
+{
+public:
+ request_handler(const request_handler&) = delete;
+ request_handler& operator=(const request_handler&) = delete;
+
+ /// Construct with a directory containing files to be served.
+ explicit request_handler(const std::string& doc_root);
+
+ /// Handle a request and produce a reply.
+ void handle_request(const request& req, reply& rep);
+
+private:
+ /// The directory containing the files to be served.
+ std::string doc_root_;
+
+ /// Perform URL-decoding on a string. Returns false if the encoding was
+ /// invalid.
+ static bool url_decode(const std::string& in, std::string& out);
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_HANDLER_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/request_parser.cpp b/3rdparty/asio/src/examples/cpp11/http/server/request_parser.cpp
new file mode 100644
index 00000000000..6812a558879
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/request_parser.cpp
@@ -0,0 +1,315 @@
+//
+// request_parser.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "request_parser.hpp"
+#include "request.hpp"
+
+namespace http {
+namespace server {
+
+request_parser::request_parser()
+ : state_(method_start)
+{
+}
+
+void request_parser::reset()
+{
+ state_ = method_start;
+}
+
+request_parser::result_type request_parser::consume(request& req, char input)
+{
+ switch (state_)
+ {
+ case method_start:
+ if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return bad;
+ }
+ else
+ {
+ state_ = method;
+ req.method.push_back(input);
+ return indeterminate;
+ }
+ case method:
+ if (input == ' ')
+ {
+ state_ = uri;
+ return indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return bad;
+ }
+ else
+ {
+ req.method.push_back(input);
+ return indeterminate;
+ }
+ case uri:
+ if (input == ' ')
+ {
+ state_ = http_version_h;
+ return indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return bad;
+ }
+ else
+ {
+ req.uri.push_back(input);
+ return indeterminate;
+ }
+ case http_version_h:
+ if (input == 'H')
+ {
+ state_ = http_version_t_1;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_t_1:
+ if (input == 'T')
+ {
+ state_ = http_version_t_2;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_t_2:
+ if (input == 'T')
+ {
+ state_ = http_version_p;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_p:
+ if (input == 'P')
+ {
+ state_ = http_version_slash;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_slash:
+ if (input == '/')
+ {
+ req.http_version_major = 0;
+ req.http_version_minor = 0;
+ state_ = http_version_major_start;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_major_start:
+ if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ state_ = http_version_major;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_major:
+ if (input == '.')
+ {
+ state_ = http_version_minor_start;
+ return indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_major = req.http_version_major * 10 + input - '0';
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_minor_start:
+ if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ state_ = http_version_minor;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case http_version_minor:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_1;
+ return indeterminate;
+ }
+ else if (is_digit(input))
+ {
+ req.http_version_minor = req.http_version_minor * 10 + input - '0';
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case expecting_newline_1:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case header_line_start:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_3;
+ return indeterminate;
+ }
+ else if (!req.headers.empty() && (input == ' ' || input == '\t'))
+ {
+ state_ = header_lws;
+ return indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return bad;
+ }
+ else
+ {
+ req.headers.push_back(header());
+ req.headers.back().name.push_back(input);
+ state_ = header_name;
+ return indeterminate;
+ }
+ case header_lws:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return indeterminate;
+ }
+ else if (input == ' ' || input == '\t')
+ {
+ return indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return bad;
+ }
+ else
+ {
+ state_ = header_value;
+ req.headers.back().value.push_back(input);
+ return indeterminate;
+ }
+ case header_name:
+ if (input == ':')
+ {
+ state_ = space_before_header_value;
+ return indeterminate;
+ }
+ else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
+ {
+ return bad;
+ }
+ else
+ {
+ req.headers.back().name.push_back(input);
+ return indeterminate;
+ }
+ case space_before_header_value:
+ if (input == ' ')
+ {
+ state_ = header_value;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case header_value:
+ if (input == '\r')
+ {
+ state_ = expecting_newline_2;
+ return indeterminate;
+ }
+ else if (is_ctl(input))
+ {
+ return bad;
+ }
+ else
+ {
+ req.headers.back().value.push_back(input);
+ return indeterminate;
+ }
+ case expecting_newline_2:
+ if (input == '\n')
+ {
+ state_ = header_line_start;
+ return indeterminate;
+ }
+ else
+ {
+ return bad;
+ }
+ case expecting_newline_3:
+ return (input == '\n') ? good : bad;
+ default:
+ return bad;
+ }
+}
+
+bool request_parser::is_char(int c)
+{
+ return c >= 0 && c <= 127;
+}
+
+bool request_parser::is_ctl(int c)
+{
+ return (c >= 0 && c <= 31) || (c == 127);
+}
+
+bool request_parser::is_tspecial(int c)
+{
+ switch (c)
+ {
+ case '(': case ')': case '<': case '>': case '@':
+ case ',': case ';': case ':': case '\\': case '"':
+ case '/': case '[': case ']': case '?': case '=':
+ case '{': case '}': case ' ': case '\t':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool request_parser::is_digit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/request_parser.hpp b/3rdparty/asio/src/examples/cpp11/http/server/request_parser.hpp
new file mode 100644
index 00000000000..643dd71c6f4
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/request_parser.hpp
@@ -0,0 +1,96 @@
+//
+// request_parser.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_REQUEST_PARSER_HPP
+#define HTTP_REQUEST_PARSER_HPP
+
+#include <tuple>
+
+namespace http {
+namespace server {
+
+struct request;
+
+/// Parser for incoming requests.
+class request_parser
+{
+public:
+ /// Construct ready to parse the request method.
+ request_parser();
+
+ /// Reset to initial parser state.
+ void reset();
+
+ /// Result of parse.
+ enum result_type { good, bad, indeterminate };
+
+ /// Parse some data. The enum return value is good when a complete request has
+ /// been parsed, bad if the data is invalid, indeterminate when more data is
+ /// required. The InputIterator return value indicates how much of the input
+ /// has been consumed.
+ template <typename InputIterator>
+ std::tuple<result_type, InputIterator> parse(request& req,
+ InputIterator begin, InputIterator end)
+ {
+ while (begin != end)
+ {
+ result_type result = consume(req, *begin++);
+ if (result == good || result == bad)
+ return std::make_tuple(result, begin);
+ }
+ return std::make_tuple(indeterminate, begin);
+ }
+
+private:
+ /// Handle the next character of input.
+ result_type consume(request& req, char input);
+
+ /// Check if a byte is an HTTP character.
+ static bool is_char(int c);
+
+ /// Check if a byte is an HTTP control character.
+ static bool is_ctl(int c);
+
+ /// Check if a byte is defined as an HTTP tspecial character.
+ static bool is_tspecial(int c);
+
+ /// Check if a byte is a digit.
+ static bool is_digit(int c);
+
+ /// The current state of the parser.
+ enum state
+ {
+ method_start,
+ method,
+ uri,
+ http_version_h,
+ http_version_t_1,
+ http_version_t_2,
+ http_version_p,
+ http_version_slash,
+ http_version_major_start,
+ http_version_major,
+ http_version_minor_start,
+ http_version_minor,
+ expecting_newline_1,
+ header_line_start,
+ header_lws,
+ header_name,
+ space_before_header_value,
+ header_value,
+ expecting_newline_2,
+ expecting_newline_3
+ } state_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_REQUEST_PARSER_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/server.cpp b/3rdparty/asio/src/examples/cpp11/http/server/server.cpp
new file mode 100644
index 00000000000..fa76a4def03
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/server.cpp
@@ -0,0 +1,94 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "server.hpp"
+#include <signal.h>
+#include <utility>
+
+namespace http {
+namespace server {
+
+server::server(const std::string& address, const std::string& port,
+ const std::string& doc_root)
+ : io_context_(1),
+ signals_(io_context_),
+ acceptor_(io_context_),
+ connection_manager_(),
+ request_handler_(doc_root)
+{
+ // Register to handle the signals that indicate when the server should exit.
+ // It is safe to register for the same signal multiple times in a program,
+ // provided all registration for the specified signal is made through Asio.
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+#if defined(SIGQUIT)
+ signals_.add(SIGQUIT);
+#endif // defined(SIGQUIT)
+
+ do_await_stop();
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ asio::ip::tcp::resolver resolver(io_context_);
+ asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ do_accept();
+}
+
+void server::run()
+{
+ // The io_context::run() call will block until all asynchronous operations
+ // have finished. While the server is running, there is always at least one
+ // asynchronous operation outstanding: the asynchronous accept call waiting
+ // for new incoming connections.
+ io_context_.run();
+}
+
+void server::do_accept()
+{
+ acceptor_.async_accept(
+ [this](std::error_code ec, asio::ip::tcp::socket socket)
+ {
+ // Check whether the server was stopped by a signal before this
+ // completion handler had a chance to run.
+ if (!acceptor_.is_open())
+ {
+ return;
+ }
+
+ if (!ec)
+ {
+ connection_manager_.start(std::make_shared<connection>(
+ std::move(socket), connection_manager_, request_handler_));
+ }
+
+ do_accept();
+ });
+}
+
+void server::do_await_stop()
+{
+ signals_.async_wait(
+ [this](std::error_code /*ec*/, int /*signo*/)
+ {
+ // The server is stopped by cancelling all outstanding asynchronous
+ // operations. Once all operations have finished the io_context::run()
+ // call will exit.
+ acceptor_.close();
+ connection_manager_.stop_all();
+ });
+}
+
+} // namespace server
+} // namespace http
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/server.hpp b/3rdparty/asio/src/examples/cpp11/http/server/server.hpp
new file mode 100644
index 00000000000..4f98f6cd07f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/http/server/server.hpp
@@ -0,0 +1,64 @@
+//
+// server.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HTTP_SERVER_HPP
+#define HTTP_SERVER_HPP
+
+#include <asio.hpp>
+#include <string>
+#include "connection.hpp"
+#include "connection_manager.hpp"
+#include "request_handler.hpp"
+
+namespace http {
+namespace server {
+
+/// The top-level class of the HTTP server.
+class server
+{
+public:
+ server(const server&) = delete;
+ server& operator=(const server&) = delete;
+
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit server(const std::string& address, const std::string& port,
+ const std::string& doc_root);
+
+ /// Run the server's io_context loop.
+ void run();
+
+private:
+ /// Perform an asynchronous accept operation.
+ void do_accept();
+
+ /// Wait for a request to stop the server.
+ void do_await_stop();
+
+ /// The io_context used to perform asynchronous operations.
+ asio::io_context io_context_;
+
+ /// The signal_set is used to register for process termination notifications.
+ asio::signal_set signals_;
+
+ /// Acceptor used to listen for incoming connections.
+ asio::ip::tcp::acceptor acceptor_;
+
+ /// The connection manager which owns all live connections.
+ connection_manager connection_manager_;
+
+ /// The handler for all incoming requests.
+ request_handler request_handler_;
+};
+
+} // namespace server
+} // namespace http
+
+#endif // HTTP_SERVER_HPP
diff --git a/3rdparty/asio/src/examples/cpp11/iostreams/.gitignore b/3rdparty/asio/src/examples/cpp11/iostreams/.gitignore
new file mode 100644
index 00000000000..bc2b4f8f7fe
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/iostreams/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+*_server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/iostreams/http_client.cpp b/3rdparty/asio/src/examples/cpp11/iostreams/http_client.cpp
new file mode 100644
index 00000000000..7972a67ecf9
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/iostreams/http_client.cpp
@@ -0,0 +1,91 @@
+//
+// http_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <asio/ip/tcp.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cout << "Usage: http_client <server> <path>\n";
+ std::cout << "Example:\n";
+ std::cout << " http_client www.boost.org /LICENSE_1_0.txt\n";
+ return 1;
+ }
+
+ asio::ip::tcp::iostream s;
+
+ // The entire sequence of I/O operations must complete within 60 seconds.
+ // If an expiry occurs, the socket is automatically closed and the stream
+ // becomes bad.
+ s.expires_after(std::chrono::seconds(60));
+
+ // Establish a connection to the server.
+ s.connect(argv[1], "http");
+ if (!s)
+ {
+ std::cout << "Unable to connect: " << s.error().message() << "\n";
+ return 1;
+ }
+
+ // Send the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ s << "GET " << argv[2] << " HTTP/1.0\r\n";
+ s << "Host: " << argv[1] << "\r\n";
+ s << "Accept: */*\r\n";
+ s << "Connection: close\r\n\r\n";
+
+ // By default, the stream is tied with itself. This means that the stream
+ // automatically flush the buffered output before attempting a read. It is
+ // not necessary not explicitly flush the stream at this point.
+
+ // Check that response is OK.
+ std::string http_version;
+ s >> http_version;
+ unsigned int status_code;
+ s >> status_code;
+ std::string status_message;
+ std::getline(s, status_message);
+ if (!s || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ return 1;
+ }
+ if (status_code != 200)
+ {
+ std::cout << "Response returned with status code " << status_code << "\n";
+ return 1;
+ }
+
+ // Process the response headers, which are terminated by a blank line.
+ std::string header;
+ while (std::getline(s, header) && header != "\r")
+ std::cout << header << "\n";
+ std::cout << "\n";
+
+ // Write the remaining data to output.
+ std::cout << s.rdbuf();
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/spawn/.gitignore b/3rdparty/asio/src/examples/cpp11/spawn/.gitignore
new file mode 100644
index 00000000000..6b8a121e099
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/spawn/.gitignore
@@ -0,0 +1,12 @@
+.deps
+.dirstamp
+parallel_grep
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp11/spawn/echo_server.cpp b/3rdparty/asio/src/examples/cpp11/spawn/echo_server.cpp
new file mode 100644
index 00000000000..5397a4efe22
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/spawn/echo_server.cpp
@@ -0,0 +1,108 @@
+//
+// echo_server.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/io_context.hpp>
+#include <asio/ip/tcp.hpp>
+#include <asio/spawn.hpp>
+#include <asio/steady_timer.hpp>
+#include <asio/write.hpp>
+#include <iostream>
+#include <memory>
+
+using asio::ip::tcp;
+
+class session : public std::enable_shared_from_this<session>
+{
+public:
+ explicit session(tcp::socket socket)
+ : socket_(std::move(socket)),
+ timer_(socket_.get_io_context()),
+ strand_(socket_.get_io_context())
+ {
+ }
+
+ void go()
+ {
+ auto self(shared_from_this());
+ asio::spawn(strand_,
+ [this, self](asio::yield_context yield)
+ {
+ try
+ {
+ char data[128];
+ for (;;)
+ {
+ timer_.expires_from_now(std::chrono::seconds(10));
+ std::size_t n = socket_.async_read_some(asio::buffer(data), yield);
+ asio::async_write(socket_, asio::buffer(data, n), yield);
+ }
+ }
+ catch (std::exception& e)
+ {
+ socket_.close();
+ timer_.cancel();
+ }
+ });
+
+ asio::spawn(strand_,
+ [this, self](asio::yield_context yield)
+ {
+ while (socket_.is_open())
+ {
+ asio::error_code ignored_ec;
+ timer_.async_wait(yield[ignored_ec]);
+ if (timer_.expires_from_now() <= std::chrono::seconds(0))
+ socket_.close();
+ }
+ });
+ }
+
+private:
+ tcp::socket socket_;
+ asio::steady_timer timer_;
+ asio::io_context::strand strand_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ asio::spawn(io_context,
+ [&](asio::yield_context yield)
+ {
+ tcp::acceptor acceptor(io_context,
+ tcp::endpoint(tcp::v4(), std::atoi(argv[1])));
+
+ for (;;)
+ {
+ asio::error_code ec;
+ tcp::socket socket(io_context);
+ acceptor.async_accept(socket, yield[ec]);
+ if (!ec) std::make_shared<session>(std::move(socket))->go();
+ }
+ });
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp11/spawn/parallel_grep.cpp b/3rdparty/asio/src/examples/cpp11/spawn/parallel_grep.cpp
new file mode 100644
index 00000000000..954d9472bbe
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp11/spawn/parallel_grep.cpp
@@ -0,0 +1,84 @@
+//
+// parallel_grep.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/dispatch.hpp>
+#include <asio/post.hpp>
+#include <asio/spawn.hpp>
+#include <asio/strand.hpp>
+#include <asio/thread_pool.hpp>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+using asio::dispatch;
+using asio::spawn;
+using asio::strand;
+using asio::thread_pool;
+using asio::yield_context;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc < 2)
+ {
+ std::cerr << "Usage: parallel_grep <string> <files...>\n";
+ return 1;
+ }
+
+ // We use a fixed size pool of threads for reading the input files. The
+ // number of threads is automatically determined based on the number of
+ // CPUs available in the system.
+ thread_pool pool;
+
+ // To prevent the output from being garbled, we use a strand to synchronise
+ // printing.
+ strand<thread_pool::executor_type> output_strand(pool.get_executor());
+
+ // Spawn a new coroutine for each file specified on the command line.
+ std::string search_string = argv[1];
+ for (int argn = 2; argn < argc; ++argn)
+ {
+ std::string input_file = argv[argn];
+ spawn(pool,
+ [=](yield_context yield)
+ {
+ std::ifstream is(input_file.c_str());
+ std::string line;
+ std::size_t line_num = 0;
+ while (std::getline(is, line))
+ {
+ // If we find a match, send a message to the output.
+ if (line.find(search_string) != std::string::npos)
+ {
+ dispatch(output_strand,
+ [=]
+ {
+ std::cout << input_file << ':' << line << std::endl;
+ });
+ }
+
+ // Every so often we yield control to another coroutine.
+ if (++line_num % 10 == 0)
+ post(yield);
+ }
+ });
+ }
+
+ // Join the thread pool to wait for all the spawned tasks to complete.
+ pool.join();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/Makefile.am b/3rdparty/asio/src/examples/cpp14/Makefile.am
new file mode 100644
index 00000000000..fb8c35689c6
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/Makefile.am
@@ -0,0 +1,48 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+if SEPARATE_COMPILATION
+noinst_LIBRARIES = libasio.a
+libasio_a_SOURCES = ../../asio.cpp
+if HAVE_OPENSSL
+libasio_a_SOURCES += ../../asio_ssl.cpp
+endif
+LDADD = libasio.a
+endif
+
+noinst_PROGRAMS = \
+ echo/async_tcp_echo_server \
+ echo/async_udp_echo_server \
+ echo/blocking_tcp_echo_client \
+ echo/blocking_tcp_echo_server \
+ echo/blocking_udp_echo_client \
+ echo/blocking_udp_echo_server \
+ executors/actor \
+ executors/async_1 \
+ executors/async_2 \
+ executors/bank_account_1 \
+ executors/bank_account_2 \
+ executors/fork_join \
+ executors/pipeline \
+ executors/priority_scheduler \
+ iostreams/http_client
+
+AM_CXXFLAGS = -I$(srcdir)/../../../include
+
+echo_async_tcp_echo_server_SOURCES = echo/async_tcp_echo_server.cpp
+echo_async_udp_echo_server_SOURCES = echo/async_udp_echo_server.cpp
+echo_blocking_tcp_echo_client_SOURCES = echo/blocking_tcp_echo_client.cpp
+echo_blocking_tcp_echo_server_SOURCES = echo/blocking_tcp_echo_server.cpp
+echo_blocking_udp_echo_client_SOURCES = echo/blocking_udp_echo_client.cpp
+echo_blocking_udp_echo_server_SOURCES = echo/blocking_udp_echo_server.cpp
+executors_actor_SOURCES = executors/actor.cpp
+executors_async_1_SOURCES = executors/async_1.cpp
+executors_async_2_SOURCES = executors/async_2.cpp
+executors_bank_account_1_SOURCES = executors/bank_account_1.cpp
+executors_bank_account_2_SOURCES = executors/bank_account_2.cpp
+executors_fork_join_SOURCES = executors/fork_join.cpp
+executors_pipeline_SOURCES = executors/pipeline.cpp
+executors_priority_scheduler_SOURCES = executors/priority_scheduler.cpp
+iostreams_http_client_SOURCES = iostreams/http_client.cpp
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
diff --git a/3rdparty/asio/src/examples/cpp14/echo/.gitignore b/3rdparty/asio/src/examples/cpp14/echo/.gitignore
new file mode 100644
index 00000000000..0882fa6ced3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_server
+*_client
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp14/echo/async_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp14/echo/async_tcp_echo_server.cpp
new file mode 100644
index 00000000000..c6004c0a0e5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/async_tcp_echo_server.cpp
@@ -0,0 +1,117 @@
+//
+// async_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <memory>
+#include <utility>
+#include <asio/ts/buffer.hpp>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::tcp;
+
+class session
+ : public std::enable_shared_from_this<session>
+{
+public:
+ session(tcp::socket socket)
+ : socket_(std::move(socket))
+ {
+ }
+
+ void start()
+ {
+ do_read();
+ }
+
+private:
+ void do_read()
+ {
+ auto self(shared_from_this());
+ socket_.async_read_some(asio::buffer(data_, max_length),
+ [this, self](std::error_code ec, std::size_t length)
+ {
+ if (!ec)
+ {
+ do_write(length);
+ }
+ });
+ }
+
+ void do_write(std::size_t length)
+ {
+ auto self(shared_from_this());
+ asio::async_write(socket_, asio::buffer(data_, length),
+ [this, self](std::error_code ec, std::size_t /*length*/)
+ {
+ if (!ec)
+ {
+ do_read();
+ }
+ });
+ }
+
+ tcp::socket socket_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
+ socket_(io_context)
+ {
+ do_accept();
+ }
+
+private:
+ void do_accept()
+ {
+ acceptor_.async_accept(socket_,
+ [this](std::error_code ec)
+ {
+ if (!ec)
+ {
+ std::make_shared<session>(std::move(socket_))->start();
+ }
+
+ do_accept();
+ });
+ }
+
+ tcp::acceptor acceptor_;
+ tcp::socket socket_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server s(io_context, std::atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/echo/async_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp14/echo/async_udp_echo_server.cpp
new file mode 100644
index 00000000000..fee8aed6e66
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/async_udp_echo_server.cpp
@@ -0,0 +1,83 @@
+//
+// async_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <asio/ts/buffer.hpp>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::udp;
+
+class server
+{
+public:
+ server(asio::io_context& io_context, short port)
+ : socket_(io_context, udp::endpoint(udp::v4(), port))
+ {
+ do_receive();
+ }
+
+ void do_receive()
+ {
+ socket_.async_receive_from(
+ asio::buffer(data_, max_length), sender_endpoint_,
+ [this](std::error_code ec, std::size_t bytes_recvd)
+ {
+ if (!ec && bytes_recvd > 0)
+ {
+ do_send(bytes_recvd);
+ }
+ else
+ {
+ do_receive();
+ }
+ });
+ }
+
+ void do_send(std::size_t length)
+ {
+ socket_.async_send_to(
+ asio::buffer(data_, length), sender_endpoint_,
+ [this](std::error_code /*ec*/, std::size_t /*bytes_sent*/)
+ {
+ do_receive();
+ });
+ }
+
+private:
+ udp::socket socket_;
+ udp::endpoint sender_endpoint_;
+ enum { max_length = 1024 };
+ char data_[max_length];
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: async_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server s(io_context, std::atoi(argv[1]));
+
+ io_context.run();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp b/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp
new file mode 100644
index 00000000000..c7c648df97f
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp
@@ -0,0 +1,55 @@
+//
+// blocking_tcp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include "asio.hpp"
+
+using asio::ip::tcp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ tcp::socket s(io_context);
+ tcp::resolver resolver(io_context);
+ asio::connect(s, resolver.resolve(argv[1], argv[2]));
+
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = std::strlen(request);
+ asio::write(s, asio::buffer(request, request_length));
+
+ char reply[max_length];
+ size_t reply_length = asio::read(s,
+ asio::buffer(reply, request_length));
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_server.cpp b/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_server.cpp
new file mode 100644
index 00000000000..d9a4f075a8d
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/blocking_tcp_echo_server.cpp
@@ -0,0 +1,77 @@
+//
+// blocking_tcp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <thread>
+#include <utility>
+#include <asio/ts/buffer.hpp>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::tcp;
+
+const int max_length = 1024;
+
+void session(tcp::socket sock)
+{
+ try
+ {
+ for (;;)
+ {
+ char data[max_length];
+
+ std::error_code error;
+ size_t length = sock.read_some(asio::buffer(data), error);
+ if (error == asio::stream_errc::eof)
+ break; // Connection closed cleanly by peer.
+ else if (error)
+ throw std::system_error(error); // Some other error.
+
+ asio::write(sock, asio::buffer(data, length));
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception in thread: " << e.what() << "\n";
+ }
+}
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
+ for (;;)
+ {
+ tcp::socket sock(io_context);
+ a.accept(sock);
+ std::thread(session, std::move(sock)).detach();
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server(io_context, std::atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp b/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp
new file mode 100644
index 00000000000..603a591f47a
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp
@@ -0,0 +1,59 @@
+//
+// blocking_udp_echo_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <asio/ts/buffer.hpp>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cerr << "Usage: blocking_udp_echo_client <host> <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ udp::socket s(io_context, udp::endpoint(udp::v4(), 0));
+
+ udp::resolver resolver(io_context);
+ udp::endpoint endpoint =
+ *resolver.resolve(udp::v4(), argv[1], argv[2]).begin();
+
+ std::cout << "Enter message: ";
+ char request[max_length];
+ std::cin.getline(request, max_length);
+ size_t request_length = std::strlen(request);
+ s.send_to(asio::buffer(request, request_length), endpoint);
+
+ char reply[max_length];
+ udp::endpoint sender_endpoint;
+ size_t reply_length = s.receive_from(
+ asio::buffer(reply, max_length), sender_endpoint);
+ std::cout << "Reply is: ";
+ std::cout.write(reply, reply_length);
+ std::cout << "\n";
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_server.cpp b/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_server.cpp
new file mode 100644
index 00000000000..646fd136649
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/echo/blocking_udp_echo_server.cpp
@@ -0,0 +1,53 @@
+//
+// blocking_udp_echo_server.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <cstdlib>
+#include <iostream>
+#include <asio/ts/buffer.hpp>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::udp;
+
+enum { max_length = 1024 };
+
+void server(asio::io_context& io_context, unsigned short port)
+{
+ udp::socket sock(io_context, udp::endpoint(udp::v4(), port));
+ for (;;)
+ {
+ char data[max_length];
+ udp::endpoint sender_endpoint;
+ size_t length = sock.receive_from(
+ asio::buffer(data, max_length), sender_endpoint);
+ sock.send_to(asio::buffer(data, length), sender_endpoint);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 2)
+ {
+ std::cerr << "Usage: blocking_udp_echo_server <port>\n";
+ return 1;
+ }
+
+ asio::io_context io_context;
+
+ server(io_context, std::atoi(argv[1]));
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/.gitignore b/3rdparty/asio/src/examples/cpp14/executors/.gitignore
new file mode 100644
index 00000000000..d51d7f00295
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/.gitignore
@@ -0,0 +1,6 @@
+actor
+async_[0-9]
+bank_account_[0-9]
+fork_join
+pipeline
+priority_scheduler
diff --git a/3rdparty/asio/src/examples/cpp14/executors/actor.cpp b/3rdparty/asio/src/examples/cpp14/executors/actor.cpp
new file mode 100644
index 00000000000..26d2fb4bf11
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/actor.cpp
@@ -0,0 +1,281 @@
+#include <asio/ts/executor.hpp>
+#include <condition_variable>
+#include <deque>
+#include <memory>
+#include <mutex>
+#include <typeinfo>
+#include <vector>
+
+using asio::defer;
+using asio::executor;
+using asio::post;
+using asio::strand;
+using asio::system_executor;
+
+//------------------------------------------------------------------------------
+// A tiny actor framework
+// ~~~~~~~~~~~~~~~~~~~~~~
+
+class actor;
+
+// Used to identify the sender and recipient of messages.
+typedef actor* actor_address;
+
+// Base class for all registered message handlers.
+class message_handler_base
+{
+public:
+ virtual ~message_handler_base() {}
+
+ // Used to determine which message handlers receive an incoming message.
+ virtual const std::type_info& message_id() const = 0;
+};
+
+// Base class for a handler for a specific message type.
+template <class Message>
+class message_handler : public message_handler_base
+{
+public:
+ // Handle an incoming message.
+ virtual void handle_message(Message msg, actor_address from) = 0;
+};
+
+// Concrete message handler for a specific message type.
+template <class Actor, class Message>
+class mf_message_handler : public message_handler<Message>
+{
+public:
+ // Construct a message handler to invoke the specified member function.
+ mf_message_handler(void (Actor::* mf)(Message, actor_address), Actor* a)
+ : function_(mf), actor_(a)
+ {
+ }
+
+ // Used to determine which message handlers receive an incoming message.
+ virtual const std::type_info& message_id() const
+ {
+ return typeid(Message);
+ }
+
+ // Handle an incoming message.
+ virtual void handle_message(Message msg, actor_address from)
+ {
+ (actor_->*function_)(std::move(msg), from);
+ }
+
+ // Determine whether the message handler represents the specified function.
+ bool is_function(void (Actor::* mf)(Message, actor_address)) const
+ {
+ return mf == function_;
+ }
+
+private:
+ void (Actor::* function_)(Message, actor_address);
+ Actor* actor_;
+};
+
+// Base class for all actors.
+class actor
+{
+public:
+ virtual ~actor()
+ {
+ }
+
+ // Obtain the actor's address for use as a message sender or recipient.
+ actor_address address()
+ {
+ return this;
+ }
+
+ // Send a message from one actor to another.
+ template <class Message>
+ friend void send(Message msg, actor_address from, actor_address to)
+ {
+ // Execute the message handler in the context of the target's executor.
+ post(to->executor_,
+ [=, msg=std::move(msg)]
+ {
+ to->call_handler(std::move(msg), from);
+ });
+ }
+
+protected:
+ // Construct the actor to use the specified executor for all message handlers.
+ actor(executor e)
+ : executor_(std::move(e))
+ {
+ }
+
+ // Register a handler for a specific message type. Duplicates are permitted.
+ template <class Actor, class Message>
+ void register_handler(void (Actor::* mf)(Message, actor_address))
+ {
+ handlers_.push_back(
+ std::make_shared<mf_message_handler<Actor, Message>>(
+ mf, static_cast<Actor*>(this)));
+ }
+
+ // Deregister a handler. Removes only the first matching handler.
+ template <class Actor, class Message>
+ void deregister_handler(void (Actor::* mf)(Message, actor_address))
+ {
+ const std::type_info& id = typeid(message_handler<Message>);
+ for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter)
+ {
+ if ((*iter)->message_id() == id)
+ {
+ auto mh = static_cast<mf_message_handler<Actor, Message>*>(iter->get());
+ if (mh->is_function(mf))
+ {
+ handlers_.erase(iter);
+ return;
+ }
+ }
+ }
+ }
+
+ // Send a message from within a message handler.
+ template <class Message>
+ void tail_send(Message msg, actor_address to)
+ {
+ // Execute the message handler in the context of the target's executor.
+ defer(to->executor_,
+ [=, msg=std::move(msg), from=this]
+ {
+ to->call_handler(std::move(msg), from);
+ });
+ }
+
+private:
+ // Find the matching message handlers, if any, and call them.
+ template <class Message>
+ void call_handler(Message msg, actor_address from)
+ {
+ const std::type_info& message_id = typeid(Message);
+ for (auto& h: handlers_)
+ {
+ if (h->message_id() == message_id)
+ {
+ auto mh = static_cast<message_handler<Message>*>(h.get());
+ mh->handle_message(msg, from);
+ }
+ }
+ }
+
+ // All messages associated with a single actor object should be processed
+ // non-concurrently. We use a strand to ensure non-concurrent execution even
+ // if the underlying executor may use multiple threads.
+ strand<executor> executor_;
+
+ std::vector<std::shared_ptr<message_handler_base>> handlers_;
+};
+
+// A concrete actor that allows synchronous message retrieval.
+template <class Message>
+class receiver : public actor
+{
+public:
+ receiver()
+ : actor(system_executor())
+ {
+ register_handler(&receiver::message_handler);
+ }
+
+ // Block until a message has been received.
+ Message wait()
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ condition_.wait(lock, [this]{ return !message_queue_.empty(); });
+ Message msg(std::move(message_queue_.front()));
+ message_queue_.pop_front();
+ return msg;
+ }
+
+private:
+ // Handle a new message by adding it to the queue and waking a waiter.
+ void message_handler(Message msg, actor_address /* from */)
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ message_queue_.push_back(std::move(msg));
+ condition_.notify_one();
+ }
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::deque<Message> message_queue_;
+};
+
+//------------------------------------------------------------------------------
+
+#include <asio/thread_pool.hpp>
+#include <iostream>
+
+using asio::thread_pool;
+
+class member : public actor
+{
+public:
+ explicit member(executor e)
+ : actor(std::move(e))
+ {
+ register_handler(&member::init_handler);
+ }
+
+private:
+ void init_handler(actor_address next, actor_address from)
+ {
+ next_ = next;
+ caller_ = from;
+
+ register_handler(&member::token_handler);
+ deregister_handler(&member::init_handler);
+ }
+
+ void token_handler(int token, actor_address /*from*/)
+ {
+ int msg(token);
+ actor_address to(caller_);
+
+ if (token > 0)
+ {
+ msg = token - 1;
+ to = next_;
+ }
+
+ tail_send(msg, to);
+ }
+
+ actor_address next_;
+ actor_address caller_;
+};
+
+int main()
+{
+ const std::size_t num_threads = 16;
+ const int num_hops = 50000000;
+ const std::size_t num_actors = 503;
+ const int token_value = (num_hops + num_actors - 1) / num_actors;
+ const std::size_t actors_per_thread = num_actors / num_threads;
+
+ struct single_thread_pool : thread_pool { single_thread_pool() : thread_pool(1) {} };
+ single_thread_pool pools[num_threads];
+ std::vector<std::shared_ptr<member>> members(num_actors);
+ receiver<int> rcvr;
+
+ // Create the member actors.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ members[i] = std::make_shared<member>(pools[(i / actors_per_thread) % num_threads].get_executor());
+
+ // Initialise the actors by passing each one the address of the next actor in the ring.
+ for (std::size_t i = num_actors, next_i = 0; i > 0; next_i = --i)
+ send(members[next_i]->address(), rcvr.address(), members[i - 1]->address());
+
+ // Send exactly one token to each actor, all with the same initial value, rounding up if required.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ send(token_value, rcvr.address(), members[i]->address());
+
+ // Wait for all signal messages, indicating the tokens have all reached zero.
+ for (std::size_t i = 0; i < num_actors; ++i)
+ rcvr.wait();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/async_1.cpp b/3rdparty/asio/src/examples/cpp14/executors/async_1.cpp
new file mode 100644
index 00000000000..d282b74f206
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/async_1.cpp
@@ -0,0 +1,47 @@
+#include <asio/ts/executor.hpp>
+#include <asio/thread_pool.hpp>
+#include <iostream>
+#include <string>
+
+using asio::bind_executor;
+using asio::dispatch;
+using asio::make_work_guard;
+using asio::post;
+using asio::thread_pool;
+
+// A function to asynchronously read a single line from an input stream.
+template <class Handler>
+void async_getline(std::istream& is, Handler handler)
+{
+ // Create executor_work for the handler's associated executor.
+ auto work = make_work_guard(handler);
+
+ // Post a function object to do the work asynchronously.
+ post([&is, work, handler=std::move(handler)]() mutable
+ {
+ std::string line;
+ std::getline(is, line);
+
+ // Pass the result to the handler, via the associated executor.
+ dispatch(work.get_executor(),
+ [line=std::move(line), handler=std::move(handler)]() mutable
+ {
+ handler(std::move(line));
+ });
+ });
+}
+
+int main()
+{
+ thread_pool pool;
+
+ std::cout << "Enter a line: ";
+
+ async_getline(std::cin,
+ bind_executor(pool, [](std::string line)
+ {
+ std::cout << "Line: " << line << "\n";
+ }));
+
+ pool.join();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/async_2.cpp b/3rdparty/asio/src/examples/cpp14/executors/async_2.cpp
new file mode 100644
index 00000000000..b39156dcb23
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/async_2.cpp
@@ -0,0 +1,68 @@
+#include <asio/ts/executor.hpp>
+#include <asio/thread_pool.hpp>
+#include <iostream>
+#include <string>
+
+using asio::bind_executor;
+using asio::dispatch;
+using asio::get_associated_executor;
+using asio::make_work_guard;
+using asio::post;
+using asio::thread_pool;
+
+// A function to asynchronously read a single line from an input stream.
+template <class Handler>
+void async_getline(std::istream& is, Handler handler)
+{
+ // Create executor_work for the handler's associated executor.
+ auto work = make_work_guard(handler);
+
+ // Post a function object to do the work asynchronously.
+ post([&is, work, handler=std::move(handler)]() mutable
+ {
+ std::string line;
+ std::getline(is, line);
+
+ // Pass the result to the handler, via the associated executor.
+ dispatch(work.get_executor(),
+ [line=std::move(line), handler=std::move(handler)]() mutable
+ {
+ handler(std::move(line));
+ });
+ });
+}
+
+// A function to asynchronously read multiple lines from an input stream.
+template <class Handler>
+void async_getlines(std::istream& is, std::string init, Handler handler)
+{
+ // Get the final handler's associated executor.
+ auto ex = get_associated_executor(handler);
+
+ // Use the associated executor for each operation in the composition.
+ async_getline(is,
+ bind_executor(ex,
+ [&is, lines=std::move(init), handler=std::move(handler)]
+ (std::string line) mutable
+ {
+ if (line.empty())
+ handler(lines);
+ else
+ async_getlines(is, lines + line + "\n", std::move(handler));
+ }));
+}
+
+int main()
+{
+ thread_pool pool;
+
+ std::cout << "Enter text, terminating with a blank line:\n";
+
+ async_getlines(std::cin, "",
+ bind_executor(pool, [](std::string lines)
+ {
+ std::cout << "Lines:\n" << lines << "\n";
+ }));
+
+ pool.join();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/bank_account_1.cpp b/3rdparty/asio/src/examples/cpp14/executors/bank_account_1.cpp
new file mode 100644
index 00000000000..f85a1852b56
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/bank_account_1.cpp
@@ -0,0 +1,54 @@
+#include <asio/ts/executor.hpp>
+#include <asio/thread_pool.hpp>
+#include <iostream>
+
+using asio::post;
+using asio::thread_pool;
+
+// Traditional active object pattern.
+// Member functions do not block.
+
+class bank_account
+{
+ int balance_ = 0;
+ mutable thread_pool pool_{1};
+
+public:
+ void deposit(int amount)
+ {
+ post(pool_, [=]
+ {
+ balance_ += amount;
+ });
+ }
+
+ void withdraw(int amount)
+ {
+ post(pool_, [=]
+ {
+ if (balance_ >= amount)
+ balance_ -= amount;
+ });
+ }
+
+ void print_balance() const
+ {
+ post(pool_, [=]
+ {
+ std::cout << "balance = " << balance_ << "\n";
+ });
+ }
+
+ ~bank_account()
+ {
+ pool_.join();
+ }
+};
+
+int main()
+{
+ bank_account acct;
+ acct.deposit(20);
+ acct.withdraw(10);
+ acct.print_balance();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/bank_account_2.cpp b/3rdparty/asio/src/examples/cpp14/executors/bank_account_2.cpp
new file mode 100644
index 00000000000..5233e77dec3
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/bank_account_2.cpp
@@ -0,0 +1,53 @@
+#include <asio/ts/executor.hpp>
+#include <asio/thread_pool.hpp>
+#include <iostream>
+
+using asio::post;
+using asio::thread_pool;
+using asio::use_future;
+
+// Traditional active object pattern.
+// Member functions block until operation is finished.
+
+class bank_account
+{
+ int balance_ = 0;
+ mutable thread_pool pool_{1};
+
+public:
+ void deposit(int amount)
+ {
+ post(pool_,
+ use_future([=]
+ {
+ balance_ += amount;
+ })).get();
+ }
+
+ void withdraw(int amount)
+ {
+ post(pool_,
+ use_future([=]
+ {
+ if (balance_ >= amount)
+ balance_ -= amount;
+ })).get();
+ }
+
+ int balance() const
+ {
+ return post(pool_,
+ use_future([=]
+ {
+ return balance_;
+ })).get();
+ }
+};
+
+int main()
+{
+ bank_account acct;
+ acct.deposit(20);
+ acct.withdraw(10);
+ std::cout << "balance = " << acct.balance() << "\n";
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/fork_join.cpp b/3rdparty/asio/src/examples/cpp14/executors/fork_join.cpp
new file mode 100644
index 00000000000..fe6746ad7e0
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/fork_join.cpp
@@ -0,0 +1,326 @@
+#include <asio/ts/executor.hpp>
+#include <asio/thread_pool.hpp>
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+using asio::dispatch;
+using asio::execution_context;
+using asio::thread_pool;
+
+// A fixed-size thread pool used to implement fork/join semantics. Functions
+// are scheduled using a simple FIFO queue. Implementing work stealing, or
+// using a queue based on atomic operations, are left as tasks for the reader.
+class fork_join_pool : public execution_context
+{
+public:
+ // The constructor starts a thread pool with the specified number of threads.
+ // Note that the thread_count is not a fixed limit on the pool's concurrency.
+ // Additional threads may temporarily be added to the pool if they join a
+ // fork_executor.
+ explicit fork_join_pool(
+ std::size_t thread_count = std::thread::hardware_concurrency() * 2)
+ : use_count_(1),
+ threads_(thread_count)
+ {
+ try
+ {
+ // Ask each thread in the pool to dequeue and execute functions until
+ // it is time to shut down, i.e. the use count is zero.
+ for (thread_count_ = 0; thread_count_ < thread_count; ++thread_count_)
+ {
+ dispatch(threads_, [&]
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (use_count_ > 0)
+ if (!execute_next(lock))
+ condition_.wait(lock);
+ });
+ }
+ }
+ catch (...)
+ {
+ stop_threads();
+ threads_.join();
+ throw;
+ }
+ }
+
+ // The destructor waits for the pool to finish executing functions.
+ ~fork_join_pool()
+ {
+ stop_threads();
+ threads_.join();
+ }
+
+private:
+ friend class fork_executor;
+
+ // The base for all functions that are queued in the pool.
+ struct function_base
+ {
+ std::shared_ptr<std::size_t> work_count_;
+ void (*execute_)(std::shared_ptr<function_base>& p);
+ };
+
+ // Execute the next function from the queue, if any. Returns true if a
+ // function was executed, and false if the queue was empty.
+ bool execute_next(std::unique_lock<std::mutex>& lock)
+ {
+ if (queue_.empty())
+ return false;
+ auto p(queue_.front());
+ queue_.pop();
+ lock.unlock();
+ execute(lock, p);
+ return true;
+ }
+
+ // Execute a function and decrement the outstanding work.
+ void execute(std::unique_lock<std::mutex>& lock,
+ std::shared_ptr<function_base>& p)
+ {
+ std::shared_ptr<std::size_t> work_count(std::move(p->work_count_));
+ try
+ {
+ p->execute_(p);
+ lock.lock();
+ do_work_finished(work_count);
+ }
+ catch (...)
+ {
+ lock.lock();
+ do_work_finished(work_count);
+ throw;
+ }
+ }
+
+ // Increment outstanding work.
+ void do_work_started(const std::shared_ptr<std::size_t>& work_count) noexcept
+ {
+ if (++(*work_count) == 1)
+ ++use_count_;
+ }
+
+ // Decrement outstanding work. Notify waiting threads if we run out.
+ void do_work_finished(const std::shared_ptr<std::size_t>& work_count) noexcept
+ {
+ if (--(*work_count) == 0)
+ {
+ --use_count_;
+ condition_.notify_all();
+ }
+ }
+
+ // Dispatch a function, executing it immediately if the queue is already
+ // loaded. Otherwise adds the function to the queue and wakes a thread.
+ void do_dispatch(std::shared_ptr<function_base> p,
+ const std::shared_ptr<std::size_t>& work_count)
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ if (queue_.size() > thread_count_ * 16)
+ {
+ do_work_started(work_count);
+ lock.unlock();
+ execute(lock, p);
+ }
+ else
+ {
+ queue_.push(p);
+ do_work_started(work_count);
+ condition_.notify_one();
+ }
+ }
+
+ // Add a function to the queue and wake a thread.
+ void do_post(std::shared_ptr<function_base> p,
+ const std::shared_ptr<std::size_t>& work_count)
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push(p);
+ do_work_started(work_count);
+ condition_.notify_one();
+ }
+
+ // Ask all threads to shut down.
+ void stop_threads()
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ --use_count_;
+ condition_.notify_all();
+ }
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::queue<std::shared_ptr<function_base>> queue_;
+ std::size_t use_count_;
+ std::size_t thread_count_;
+ thread_pool threads_;
+};
+
+// A class that satisfies the Executor requirements. Every function or piece of
+// work associated with a fork_executor is part of a single, joinable group.
+class fork_executor
+{
+public:
+ fork_executor(fork_join_pool& ctx)
+ : context_(ctx),
+ work_count_(std::make_shared<std::size_t>(0))
+ {
+ }
+
+ fork_join_pool& context() const noexcept
+ {
+ return context_;
+ }
+
+ void on_work_started() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.do_work_started(work_count_);
+ }
+
+ void on_work_finished() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.do_work_finished(work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<function<Func>>(
+ typename std::allocator_traits<Alloc>::template rebind_alloc<char>(a),
+ std::move(f), work_count_));
+ context_.do_dispatch(p, work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<function<Func>>(
+ typename std::allocator_traits<Alloc>::template rebind_alloc<char>(a),
+ std::move(f), work_count_));
+ context_.do_post(p, work_count_);
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const fork_executor& a,
+ const fork_executor& b) noexcept
+ {
+ return a.work_count_ == b.work_count_;
+ }
+
+ friend bool operator!=(const fork_executor& a,
+ const fork_executor& b) noexcept
+ {
+ return a.work_count_ != b.work_count_;
+ }
+
+ // Block until all work associated with the executor is complete. While it is
+ // waiting, the thread may be borrowed to execute functions from the queue.
+ void join() const
+ {
+ std::unique_lock<std::mutex> lock(context_.mutex_);
+ while (*work_count_ > 0)
+ if (!context_.execute_next(lock))
+ context_.condition_.wait(lock);
+ }
+
+private:
+ template <class Func>
+ struct function : fork_join_pool::function_base
+ {
+ explicit function(Func f, const std::shared_ptr<std::size_t>& w)
+ : function_(std::move(f))
+ {
+ work_count_ = w;
+ execute_ = [](std::shared_ptr<fork_join_pool::function_base>& p)
+ {
+ Func tmp(std::move(static_cast<function*>(p.get())->function_));
+ p.reset();
+ tmp();
+ };
+ }
+
+ Func function_;
+ };
+
+ fork_join_pool& context_;
+ std::shared_ptr<std::size_t> work_count_;
+};
+
+// Helper class to automatically join a fork_executor when exiting a scope.
+class join_guard
+{
+public:
+ explicit join_guard(const fork_executor& ex) : ex_(ex) {}
+ join_guard(const join_guard&) = delete;
+ join_guard(join_guard&&) = delete;
+ ~join_guard() { ex_.join(); }
+
+private:
+ fork_executor ex_;
+};
+
+//------------------------------------------------------------------------------
+
+#include <algorithm>
+#include <iostream>
+#include <random>
+#include <vector>
+
+fork_join_pool pool;
+
+template <class Iterator>
+void fork_join_sort(Iterator begin, Iterator end)
+{
+ std::size_t n = end - begin;
+ if (n > 32768)
+ {
+ {
+ fork_executor fork(pool);
+ join_guard join(fork);
+ dispatch(fork, [=]{ fork_join_sort(begin, begin + n / 2); });
+ dispatch(fork, [=]{ fork_join_sort(begin + n / 2, end); });
+ }
+ std::inplace_merge(begin, begin + n / 2, end);
+ }
+ else
+ {
+ std::sort(begin, end);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cerr << "Usage: fork_join <size>\n";
+ return 1;
+ }
+
+ std::vector<double> vec(std::atoll(argv[1]));
+ std::iota(vec.begin(), vec.end(), 0);
+
+ std::random_device rd;
+ std::mt19937 g(rd());
+ std::shuffle(vec.begin(), vec.end(), g);
+
+ std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
+
+ fork_join_sort(vec.begin(), vec.end());
+
+ std::chrono::steady_clock::duration elapsed = std::chrono::steady_clock::now() - start;
+
+ std::cout << "sort took ";
+ std::cout << std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
+ std::cout << " microseconds" << std::endl;
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/pipeline.cpp b/3rdparty/asio/src/examples/cpp14/executors/pipeline.cpp
new file mode 100644
index 00000000000..c66e283fcbc
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/pipeline.cpp
@@ -0,0 +1,293 @@
+#include <asio/ts/executor.hpp>
+#include <condition_variable>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+#include <vector>
+
+using asio::execution_context;
+using asio::executor_binder;
+using asio::get_associated_executor;
+using asio::post;
+using asio::system_executor;
+using asio::use_future;
+using asio::use_service;
+
+// An executor that launches a new thread for each function submitted to it.
+// This class satisfies the Executor requirements.
+class thread_executor
+{
+private:
+ // Service to track all threads started through a thread_executor.
+ class thread_bag : public execution_context::service
+ {
+ public:
+ typedef thread_bag key_type;
+
+ explicit thread_bag(execution_context& ctx)
+ : execution_context::service(ctx)
+ {
+ }
+
+ void add_thread(std::thread&& t)
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ threads_.push_back(std::move(t));
+ }
+
+ private:
+ virtual void shutdown()
+ {
+ for (auto& t : threads_)
+ t.join();
+ }
+
+ std::mutex mutex_;
+ std::vector<std::thread> threads_;
+ };
+
+public:
+ execution_context& context() const noexcept
+ {
+ return system_executor().context();
+ }
+
+ void on_work_started() const noexcept
+ {
+ // This executor doesn't count work.
+ }
+
+ void on_work_finished() const noexcept
+ {
+ // This executor doesn't count work.
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc&) const
+ {
+ thread_bag& bag = use_service<thread_bag>(context());
+ bag.add_thread(std::thread(std::move(f)));
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const thread_executor&,
+ const thread_executor&) noexcept
+ {
+ return true;
+ }
+
+ friend bool operator!=(const thread_executor&,
+ const thread_executor&) noexcept
+ {
+ return false;
+ }
+};
+
+// Base class for all thread-safe queue implementations.
+class queue_impl_base
+{
+ template <class> friend class queue_front;
+ template <class> friend class queue_back;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool stop_ = false;
+};
+
+// Underlying implementation of a thread-safe queue, shared between the
+// queue_front and queue_back classes.
+template <class T>
+class queue_impl : public queue_impl_base
+{
+ template <class> friend class queue_front;
+ template <class> friend class queue_back;
+ std::queue<T> queue_;
+};
+
+// The front end of a queue between consecutive pipeline stages.
+template <class T>
+class queue_front
+{
+public:
+ typedef T value_type;
+
+ explicit queue_front(std::shared_ptr<queue_impl<T>> impl)
+ : impl_(impl)
+ {
+ }
+
+ void push(T t)
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ impl_->queue_.push(std::move(t));
+ impl_->condition_.notify_one();
+ }
+
+ void stop()
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ impl_->stop_ = true;
+ impl_->condition_.notify_one();
+ }
+
+private:
+ std::shared_ptr<queue_impl<T>> impl_;
+};
+
+// The back end of a queue between consecutive pipeline stages.
+template <class T>
+class queue_back
+{
+public:
+ typedef T value_type;
+
+ explicit queue_back(std::shared_ptr<queue_impl<T>> impl)
+ : impl_(impl)
+ {
+ }
+
+ bool pop(T& t)
+ {
+ std::unique_lock<std::mutex> lock(impl_->mutex_);
+ while (impl_->queue_.empty() && !impl_->stop_)
+ impl_->condition_.wait(lock);
+ if (!impl_->queue_.empty())
+ {
+ t = impl_->queue_.front();
+ impl_->queue_.pop();
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::shared_ptr<queue_impl<T>> impl_;
+};
+
+// Launch the last stage in a pipeline.
+template <class T, class F>
+std::future<void> pipeline(queue_back<T> in, F f)
+{
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function, and as we're the last stage return a future so that the
+ // caller can wait for the pipeline to finish.
+ return post(ex, use_future([in, f = std::move(f)]() mutable { f(in); }));
+}
+
+// Launch an intermediate stage in a pipeline.
+template <class T, class F, class... Tail>
+std::future<void> pipeline(queue_back<T> in, F f, Tail... t)
+{
+ // Determine the output queue type.
+ typedef typename executor_binder<F, thread_executor>::second_argument_type::value_type output_value_type;
+
+ // Create the output queue and its implementation.
+ auto out_impl = std::make_shared<queue_impl<output_value_type>>();
+ queue_front<output_value_type> out(out_impl);
+ queue_back<output_value_type> next_in(out_impl);
+
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function.
+ post(ex, [in, out, f = std::move(f)]() mutable
+ {
+ f(in, out);
+ out.stop();
+ });
+
+ // Launch the rest of the pipeline.
+ return pipeline(next_in, std::move(t)...);
+}
+
+// Launch the first stage in a pipeline.
+template <class F, class... Tail>
+std::future<void> pipeline(F f, Tail... t)
+{
+ // Determine the output queue type.
+ typedef typename executor_binder<F, thread_executor>::argument_type::value_type output_value_type;
+
+ // Create the output queue and its implementation.
+ auto out_impl = std::make_shared<queue_impl<output_value_type>>();
+ queue_front<output_value_type> out(out_impl);
+ queue_back<output_value_type> next_in(out_impl);
+
+ // Get the function's associated executor, defaulting to thread_executor.
+ auto ex = get_associated_executor(f, thread_executor());
+
+ // Run the function.
+ post(ex, [out, f = std::move(f)]() mutable
+ {
+ f(out);
+ out.stop();
+ });
+
+ // Launch the rest of the pipeline.
+ return pipeline(next_in, std::move(t)...);
+}
+
+//------------------------------------------------------------------------------
+
+#include <asio/thread_pool.hpp>
+#include <iostream>
+#include <string>
+
+using asio::bind_executor;
+using asio::thread_pool;
+
+void reader(queue_front<std::string> out)
+{
+ std::string line;
+ while (std::getline(std::cin, line))
+ out.push(line);
+}
+
+void filter(queue_back<std::string> in, queue_front<std::string> out)
+{
+ std::string line;
+ while (in.pop(line))
+ if (line.length() > 5)
+ out.push(line);
+}
+
+void upper(queue_back<std::string> in, queue_front<std::string> out)
+{
+ std::string line;
+ while (in.pop(line))
+ {
+ std::string new_line;
+ for (char c : line)
+ new_line.push_back(std::toupper(c));
+ out.push(new_line);
+ }
+}
+
+void writer(queue_back<std::string> in)
+{
+ std::size_t count = 0;
+ std::string line;
+ while (in.pop(line))
+ std::cout << count++ << ": " << line << std::endl;
+}
+
+int main()
+{
+ thread_pool pool;
+
+ auto f = pipeline(reader, filter, bind_executor(pool, upper), writer);
+ f.wait();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/executors/priority_scheduler.cpp b/3rdparty/asio/src/examples/cpp14/executors/priority_scheduler.cpp
new file mode 100644
index 00000000000..3b28af1eec0
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/executors/priority_scheduler.cpp
@@ -0,0 +1,167 @@
+#include <asio/ts/executor.hpp>
+#include <condition_variable>
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <queue>
+
+using asio::dispatch;
+using asio::execution_context;
+
+class priority_scheduler : public execution_context
+{
+public:
+ // A class that satisfies the Executor requirements.
+ class executor_type
+ {
+ public:
+ executor_type(priority_scheduler& ctx, int pri) noexcept
+ : context_(ctx), priority_(pri)
+ {
+ }
+
+ priority_scheduler& context() const noexcept
+ {
+ return context_;
+ }
+
+ void on_work_started() const noexcept
+ {
+ // This executor doesn't count work. Instead, the scheduler simply runs
+ // until explicitly stopped.
+ }
+
+ void on_work_finished() const noexcept
+ {
+ // This executor doesn't count work. Instead, the scheduler simply runs
+ // until explicitly stopped.
+ }
+
+ template <class Func, class Alloc>
+ void dispatch(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ template <class Func, class Alloc>
+ void post(Func f, const Alloc& a) const
+ {
+ auto p(std::allocate_shared<item<Func>>(
+ typename std::allocator_traits<
+ Alloc>::template rebind_alloc<char>(a),
+ priority_, std::move(f)));
+ std::lock_guard<std::mutex> lock(context_.mutex_);
+ context_.queue_.push(p);
+ context_.condition_.notify_one();
+ }
+
+ template <class Func, class Alloc>
+ void defer(Func&& f, const Alloc& a) const
+ {
+ post(std::forward<Func>(f), a);
+ }
+
+ friend bool operator==(const executor_type& a,
+ const executor_type& b) noexcept
+ {
+ return &a.context_ == &b.context_;
+ }
+
+ friend bool operator!=(const executor_type& a,
+ const executor_type& b) noexcept
+ {
+ return &a.context_ != &b.context_;
+ }
+
+ private:
+ priority_scheduler& context_;
+ int priority_;
+ };
+
+ executor_type get_executor(int pri = 0) noexcept
+ {
+ return executor_type(*const_cast<priority_scheduler*>(this), pri);
+ }
+
+ void run()
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+ for (;;)
+ {
+ condition_.wait(lock, [&]{ return stopped_ || !queue_.empty(); });
+ if (stopped_)
+ return;
+ auto p(queue_.top());
+ queue_.pop();
+ lock.unlock();
+ p->execute_(p);
+ lock.lock();
+ }
+ }
+
+ void stop()
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ stopped_ = true;
+ condition_.notify_all();
+ }
+
+private:
+ struct item_base
+ {
+ int priority_;
+ void (*execute_)(std::shared_ptr<item_base>&);
+ };
+
+ template <class Func>
+ struct item : item_base
+ {
+ item(int pri, Func f) : function_(std::move(f))
+ {
+ priority_ = pri;
+ execute_ = [](std::shared_ptr<item_base>& p)
+ {
+ Func tmp(std::move(static_cast<item*>(p.get())->function_));
+ p.reset();
+ tmp();
+ };
+ }
+
+ Func function_;
+ };
+
+ struct item_comp
+ {
+ bool operator()(
+ const std::shared_ptr<item_base>& a,
+ const std::shared_ptr<item_base>& b)
+ {
+ return a->priority_ < b->priority_;
+ }
+ };
+
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::priority_queue<
+ std::shared_ptr<item_base>,
+ std::vector<std::shared_ptr<item_base>>,
+ item_comp> queue_;
+ bool stopped_ = false;
+};
+
+int main()
+{
+ priority_scheduler sched;
+ auto low = sched.get_executor(0);
+ auto med = sched.get_executor(1);
+ auto high = sched.get_executor(2);
+ dispatch(low, []{ std::cout << "1\n"; });
+ dispatch(low, []{ std::cout << "11\n"; });
+ dispatch(med, []{ std::cout << "2\n"; });
+ dispatch(med, []{ std::cout << "22\n"; });
+ dispatch(high, []{ std::cout << "3\n"; });
+ dispatch(high, []{ std::cout << "33\n"; });
+ dispatch(high, []{ std::cout << "333\n"; });
+ dispatch(sched.get_executor(-1), [&]{ sched.stop(); });
+ sched.run();
+}
diff --git a/3rdparty/asio/src/examples/cpp14/iostreams/.gitignore b/3rdparty/asio/src/examples/cpp14/iostreams/.gitignore
new file mode 100644
index 00000000000..bc2b4f8f7fe
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/iostreams/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_client
+*_server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/examples/cpp14/iostreams/http_client.cpp b/3rdparty/asio/src/examples/cpp14/iostreams/http_client.cpp
new file mode 100644
index 00000000000..36f14b459e5
--- /dev/null
+++ b/3rdparty/asio/src/examples/cpp14/iostreams/http_client.cpp
@@ -0,0 +1,91 @@
+//
+// http_client.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <asio/ts/internet.hpp>
+
+using asio::ip::tcp;
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 3)
+ {
+ std::cout << "Usage: http_client <server> <path>\n";
+ std::cout << "Example:\n";
+ std::cout << " http_client www.boost.org /LICENSE_1_0.txt\n";
+ return 1;
+ }
+
+ asio::ip::tcp::iostream s;
+
+ // The entire sequence of I/O operations must complete within 60 seconds.
+ // If an expiry occurs, the socket is automatically closed and the stream
+ // becomes bad.
+ s.expires_after(std::chrono::seconds(60));
+
+ // Establish a connection to the server.
+ s.connect(argv[1], "http");
+ if (!s)
+ {
+ std::cout << "Unable to connect: " << s.error().message() << "\n";
+ return 1;
+ }
+
+ // Send the request. We specify the "Connection: close" header so that the
+ // server will close the socket after transmitting the response. This will
+ // allow us to treat all data up until the EOF as the content.
+ s << "GET " << argv[2] << " HTTP/1.0\r\n";
+ s << "Host: " << argv[1] << "\r\n";
+ s << "Accept: */*\r\n";
+ s << "Connection: close\r\n\r\n";
+
+ // By default, the stream is tied with itself. This means that the stream
+ // automatically flush the buffered output before attempting a read. It is
+ // not necessary not explicitly flush the stream at this point.
+
+ // Check that response is OK.
+ std::string http_version;
+ s >> http_version;
+ unsigned int status_code;
+ s >> status_code;
+ std::string status_message;
+ std::getline(s, status_message);
+ if (!s || http_version.substr(0, 5) != "HTTP/")
+ {
+ std::cout << "Invalid response\n";
+ return 1;
+ }
+ if (status_code != 200)
+ {
+ std::cout << "Response returned with status code " << status_code << "\n";
+ return 1;
+ }
+
+ // Process the response headers, which are terminated by a blank line.
+ std::string header;
+ while (std::getline(s, header) && header != "\r")
+ std::cout << header << "\n";
+ std::cout << "\n";
+
+ // Write the remaining data to output.
+ std::cout << s.rdbuf();
+ }
+ catch (std::exception& e)
+ {
+ std::cout << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/tests/.gitignore b/3rdparty/asio/src/tests/.gitignore
new file mode 100644
index 00000000000..a35502b4e5d
--- /dev/null
+++ b/3rdparty/asio/src/tests/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*_test
+*.ilk
+*.manifest
+*.pdb
+*.tds
+*.winmd
diff --git a/3rdparty/asio/src/tests/Makefile.am b/3rdparty/asio/src/tests/Makefile.am
new file mode 100644
index 00000000000..381377f2288
--- /dev/null
+++ b/3rdparty/asio/src/tests/Makefile.am
@@ -0,0 +1,416 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+if SEPARATE_COMPILATION
+noinst_LIBRARIES = libasio.a
+libasio_a_SOURCES = ../asio.cpp
+if HAVE_OPENSSL
+libasio_a_SOURCES += ../asio_ssl.cpp
+endif
+LDADD = libasio.a
+endif
+
+check_PROGRAMS = \
+ unit/associated_allocator \
+ unit/associated_executor \
+ unit/async_result \
+ unit/basic_datagram_socket \
+ unit/basic_deadline_timer \
+ unit/basic_raw_socket \
+ unit/basic_seq_packet_socket \
+ unit/basic_serial_port \
+ unit/basic_signal_set \
+ unit/basic_socket_acceptor \
+ unit/basic_stream_socket \
+ unit/basic_streambuf \
+ unit/basic_waitable_timer \
+ unit/bind_executor \
+ unit/buffered_read_stream \
+ unit/buffered_stream \
+ unit/buffered_write_stream \
+ unit/buffer \
+ unit/buffers_iterator \
+ unit/completion_condition \
+ unit/connect \
+ unit/coroutine \
+ unit/datagram_socket_service \
+ unit/deadline_timer_service \
+ unit/deadline_timer \
+ unit/defer \
+ unit/dispatch \
+ unit/error \
+ unit/execution_context \
+ unit/executor \
+ unit/executor_work_guard \
+ unit/generic/basic_endpoint \
+ unit/generic/datagram_protocol \
+ unit/generic/raw_protocol \
+ unit/generic/seq_packet_protocol \
+ unit/generic/stream_protocol \
+ unit/high_resolution_timer \
+ unit/io_context \
+ unit/ip/address \
+ unit/ip/address_v4 \
+ unit/ip/address_v4_iterator \
+ unit/ip/address_v4_range \
+ unit/ip/address_v6 \
+ unit/ip/address_v6_iterator \
+ unit/ip/address_v6_range \
+ unit/ip/basic_endpoint \
+ unit/ip/basic_resolver \
+ unit/ip/basic_resolver_entry \
+ unit/ip/basic_resolver_iterator \
+ unit/ip/basic_resolver_query \
+ unit/ip/host_name \
+ unit/ip/icmp \
+ unit/ip/multicast \
+ unit/ip/network_v4 \
+ unit/ip/network_v6 \
+ unit/ip/resolver_query_base \
+ unit/ip/resolver_service \
+ unit/ip/tcp \
+ unit/ip/udp \
+ unit/ip/unicast \
+ unit/ip/v6_only \
+ unit/is_read_buffered \
+ unit/is_write_buffered \
+ unit/local/basic_endpoint \
+ unit/local/connect_pair \
+ unit/local/datagram_protocol \
+ unit/local/stream_protocol \
+ unit/packaged_task \
+ unit/placeholders \
+ unit/posix/basic_descriptor \
+ unit/posix/basic_stream_descriptor \
+ unit/posix/descriptor \
+ unit/posix/descriptor_base \
+ unit/posix/stream_descriptor \
+ unit/posix/stream_descriptor_service \
+ unit/post \
+ unit/raw_socket_service \
+ unit/read \
+ unit/read_at \
+ unit/read_until \
+ unit/seq_packet_socket_service \
+ unit/serial_port \
+ unit/serial_port_base \
+ unit/serial_port_service \
+ unit/signal_set \
+ unit/signal_set_service \
+ unit/socket_acceptor_service \
+ unit/socket_base \
+ unit/steady_timer \
+ unit/strand \
+ unit/stream_socket_service \
+ unit/streambuf \
+ unit/system_timer \
+ unit/thread \
+ unit/time_traits \
+ unit/use_future \
+ unit/uses_executor \
+ unit/wait_traits \
+ unit/waitable_timer_service \
+ unit/windows/basic_handle \
+ unit/windows/basic_object_handle \
+ unit/windows/basic_random_access_handle \
+ unit/windows/basic_stream_handle \
+ unit/windows/object_handle \
+ unit/windows/object_handle_service \
+ unit/windows/overlapped_handle \
+ unit/windows/overlapped_ptr \
+ unit/windows/random_access_handle \
+ unit/windows/random_access_handle_service \
+ unit/windows/stream_handle \
+ unit/windows/stream_handle_service \
+ unit/write \
+ unit/write_at
+
+if !STANDALONE
+noinst_PROGRAMS = \
+ latency/tcp_client \
+ latency/tcp_server \
+ latency/udp_client \
+ latency/udp_server \
+ performance/client \
+ performance/server
+endif
+
+if HAVE_OPENSSL
+check_PROGRAMS += \
+ unit/ssl/context_base \
+ unit/ssl/context \
+ unit/ssl/rfc2818_verification \
+ unit/ssl/stream_base \
+ unit/ssl/stream
+endif
+
+TESTS = \
+ unit/associated_allocator \
+ unit/associated_executor \
+ unit/async_result \
+ unit/basic_datagram_socket \
+ unit/basic_deadline_timer \
+ unit/basic_raw_socket \
+ unit/basic_seq_packet_socket \
+ unit/basic_serial_port \
+ unit/basic_signal_set \
+ unit/basic_socket_acceptor \
+ unit/basic_stream_socket \
+ unit/basic_streambuf \
+ unit/basic_waitable_timer \
+ unit/bind_executor \
+ unit/buffered_read_stream \
+ unit/buffered_stream \
+ unit/buffered_write_stream \
+ unit/buffer \
+ unit/buffers_iterator \
+ unit/completion_condition \
+ unit/connect \
+ unit/datagram_socket_service \
+ unit/deadline_timer_service \
+ unit/deadline_timer \
+ unit/defer \
+ unit/dispatch \
+ unit/error \
+ unit/execution_context \
+ unit/executor \
+ unit/executor_work_guard \
+ unit/high_resolution_timer \
+ unit/io_context \
+ unit/ip/address \
+ unit/ip/address_v4 \
+ unit/ip/address_v4_iterator \
+ unit/ip/address_v4_range \
+ unit/ip/address_v6 \
+ unit/ip/address_v6_iterator \
+ unit/ip/address_v6_range \
+ unit/ip/basic_endpoint \
+ unit/ip/basic_resolver \
+ unit/ip/basic_resolver_entry \
+ unit/ip/basic_resolver_iterator \
+ unit/ip/basic_resolver_query \
+ unit/ip/host_name \
+ unit/ip/icmp \
+ unit/ip/multicast \
+ unit/ip/network_v4 \
+ unit/ip/network_v6 \
+ unit/ip/resolver_query_base \
+ unit/ip/resolver_service \
+ unit/ip/tcp \
+ unit/ip/udp \
+ unit/ip/unicast \
+ unit/ip/v6_only \
+ unit/is_read_buffered \
+ unit/is_write_buffered \
+ unit/local/basic_endpoint \
+ unit/local/connect_pair \
+ unit/local/datagram_protocol \
+ unit/local/stream_protocol \
+ unit/packaged_task \
+ unit/placeholders \
+ unit/posix/basic_descriptor \
+ unit/posix/basic_stream_descriptor \
+ unit/posix/descriptor\
+ unit/posix/descriptor_base \
+ unit/posix/stream_descriptor \
+ unit/posix/stream_descriptor_service \
+ unit/post \
+ unit/raw_socket_service \
+ unit/read \
+ unit/read_at \
+ unit/read_until \
+ unit/seq_packet_socket_service \
+ unit/serial_port \
+ unit/serial_port_base \
+ unit/serial_port_service \
+ unit/signal_set \
+ unit/signal_set_service \
+ unit/socket_acceptor_service \
+ unit/socket_base \
+ unit/steady_timer \
+ unit/strand \
+ unit/stream_socket_service \
+ unit/streambuf \
+ unit/system_timer \
+ unit/thread \
+ unit/time_traits \
+ unit/use_future \
+ unit/uses_executor \
+ unit/wait_traits \
+ unit/waitable_timer_service \
+ unit/windows/basic_handle \
+ unit/windows/basic_object_handle \
+ unit/windows/basic_random_access_handle \
+ unit/windows/basic_stream_handle \
+ unit/windows/object_handle \
+ unit/windows/object_handle_service \
+ unit/windows/overlapped_handle \
+ unit/windows/overlapped_ptr \
+ unit/windows/random_access_handle \
+ unit/windows/random_access_handle_service \
+ unit/windows/stream_handle \
+ unit/windows/stream_handle_service \
+ unit/write \
+ unit/write_at
+
+if HAVE_OPENSSL
+TESTS += \
+ unit/ssl/context_base \
+ unit/ssl/context \
+ unit/ssl/rfc2818_verification \
+ unit/ssl/stream_base \
+ unit/ssl/stream
+endif
+
+noinst_HEADERS = \
+ latency/coroutine.hpp \
+ latency/high_res_clock.hpp \
+ latency/unyield.hpp \
+ latency/yield.hpp \
+ unit/unit_test.hpp
+
+AM_CXXFLAGS = -I$(srcdir)/../../include
+
+if !STANDALONE
+latency_tcp_client_SOURCES = latency/tcp_client.cpp
+latency_tcp_server_SOURCES = latency/tcp_server.cpp
+latency_udp_client_SOURCES = latency/udp_client.cpp
+latency_udp_server_SOURCES = latency/udp_server.cpp
+performance_client_SOURCES = performance/client.cpp
+performance_server_SOURCES = performance/server.cpp
+endif
+
+unit_associated_allocator_SOURCES = unit/associated_allocator.cpp
+unit_associated_executor_SOURCES = unit/associated_executor.cpp
+unit_async_result_SOURCES = unit/async_result.cpp
+unit_basic_datagram_socket_SOURCES = unit/basic_datagram_socket.cpp
+unit_basic_deadline_timer_SOURCES = unit/basic_deadline_timer.cpp
+unit_basic_raw_socket_SOURCES = unit/basic_raw_socket.cpp
+unit_basic_seq_packet_socket_SOURCES = unit/basic_seq_packet_socket.cpp
+unit_basic_serial_port_SOURCES = unit/basic_serial_port.cpp
+unit_basic_signal_set_SOURCES = unit/basic_signal_set.cpp
+unit_basic_socket_acceptor_SOURCES = unit/basic_socket_acceptor.cpp
+unit_basic_stream_socket_SOURCES = unit/basic_stream_socket.cpp
+unit_basic_streambuf_SOURCES = unit/basic_streambuf.cpp
+unit_basic_waitable_timer_SOURCES = unit/basic_waitable_timer.cpp
+unit_bind_executor_SOURCES = unit/bind_executor.cpp
+unit_buffer_SOURCES = unit/buffer.cpp
+unit_buffers_iterator_SOURCES = unit/buffers_iterator.cpp
+unit_buffered_read_stream_SOURCES = unit/buffered_read_stream.cpp
+unit_buffered_stream_SOURCES = unit/buffered_stream.cpp
+unit_buffered_write_stream_SOURCES = unit/buffered_write_stream.cpp
+unit_completion_condition_SOURCES = unit/completion_condition.cpp
+unit_connect_SOURCES = unit/connect.cpp
+unit_coroutine_SOURCES = unit/coroutine.cpp
+unit_datagram_socket_service_SOURCES = unit/datagram_socket_service.cpp
+unit_deadline_timer_service_SOURCES = unit/deadline_timer_service.cpp
+unit_deadline_timer_SOURCES = unit/deadline_timer.cpp
+unit_defer_SOURCES = unit/defer.cpp
+unit_dispatch_SOURCES = unit/dispatch.cpp
+unit_error_SOURCES = unit/error.cpp
+unit_execution_context_SOURCES = unit/execution_context.cpp
+unit_executor_SOURCES = unit/executor.cpp
+unit_executor_work_guard_SOURCES = unit/executor_work_guard.cpp
+unit_generic_basic_endpoint_SOURCES = unit/generic/basic_endpoint.cpp
+unit_generic_datagram_protocol_SOURCES = unit/generic/datagram_protocol.cpp
+unit_generic_raw_protocol_SOURCES = unit/generic/raw_protocol.cpp
+unit_generic_seq_packet_protocol_SOURCES = unit/generic/seq_packet_protocol.cpp
+unit_generic_stream_protocol_SOURCES = unit/generic/stream_protocol.cpp
+unit_high_resolution_timer_SOURCES = unit/high_resolution_timer.cpp
+unit_io_context_SOURCES = unit/io_context.cpp
+unit_ip_address_SOURCES = unit/ip/address.cpp
+unit_ip_address_v4_SOURCES = unit/ip/address_v4.cpp
+unit_ip_address_v4_iterator_SOURCES = unit/ip/address_v4_iterator.cpp
+unit_ip_address_v4_range_SOURCES = unit/ip/address_v4_range.cpp
+unit_ip_address_v6_SOURCES = unit/ip/address_v6.cpp
+unit_ip_address_v6_iterator_SOURCES = unit/ip/address_v6_iterator.cpp
+unit_ip_address_v6_range_SOURCES = unit/ip/address_v6_range.cpp
+unit_ip_basic_endpoint_SOURCES = unit/ip/basic_endpoint.cpp
+unit_ip_basic_resolver_SOURCES = unit/ip/basic_resolver.cpp
+unit_ip_basic_resolver_entry_SOURCES = unit/ip/basic_resolver_entry.cpp
+unit_ip_basic_resolver_iterator_SOURCES = unit/ip/basic_resolver_iterator.cpp
+unit_ip_basic_resolver_query_SOURCES = unit/ip/basic_resolver_query.cpp
+unit_ip_host_name_SOURCES = unit/ip/host_name.cpp
+unit_ip_icmp_SOURCES = unit/ip/icmp.cpp
+unit_ip_multicast_SOURCES = unit/ip/multicast.cpp
+unit_ip_network_v4_SOURCES = unit/ip/network_v4.cpp
+unit_ip_network_v6_SOURCES = unit/ip/network_v6.cpp
+unit_ip_resolver_query_base_SOURCES = unit/ip/resolver_query_base.cpp
+unit_ip_resolver_service_SOURCES = unit/ip/resolver_service.cpp
+unit_ip_tcp_SOURCES = unit/ip/tcp.cpp
+unit_ip_udp_SOURCES = unit/ip/udp.cpp
+unit_ip_unicast_SOURCES = unit/ip/unicast.cpp
+unit_ip_v6_only_SOURCES = unit/ip/v6_only.cpp
+unit_is_read_buffered_SOURCES = unit/is_read_buffered.cpp
+unit_is_write_buffered_SOURCES = unit/is_write_buffered.cpp
+unit_local_basic_endpoint_SOURCES = unit/local/basic_endpoint.cpp
+unit_local_connect_pair_SOURCES = unit/local/connect_pair.cpp
+unit_local_datagram_protocol_SOURCES = unit/local/datagram_protocol.cpp
+unit_local_stream_protocol_SOURCES = unit/local/stream_protocol.cpp
+unit_packaged_task_SOURCES = unit/packaged_task.cpp
+unit_placeholders_SOURCES = unit/placeholders.cpp
+unit_posix_basic_descriptor_SOURCES = unit/posix/basic_descriptor.cpp
+unit_posix_basic_stream_descriptor_SOURCES = unit/posix/basic_stream_descriptor.cpp
+unit_posix_descriptor_SOURCES = unit/posix/descriptor.cpp
+unit_posix_descriptor_base_SOURCES = unit/posix/descriptor_base.cpp
+unit_posix_stream_descriptor_SOURCES = unit/posix/stream_descriptor.cpp
+unit_posix_stream_descriptor_service_SOURCES = unit/posix/stream_descriptor_service.cpp
+unit_post_SOURCES = unit/post.cpp
+unit_raw_socket_service_SOURCES = unit/raw_socket_service.cpp
+unit_read_SOURCES = unit/read.cpp
+unit_read_at_SOURCES = unit/read_at.cpp
+unit_read_until_SOURCES = unit/read_until.cpp
+unit_seq_packet_socket_service_SOURCES = unit/seq_packet_socket_service.cpp
+unit_serial_port_SOURCES = unit/serial_port.cpp
+unit_serial_port_base_SOURCES = unit/serial_port_base.cpp
+unit_serial_port_service_SOURCES = unit/serial_port_service.cpp
+unit_signal_set_SOURCES = unit/signal_set.cpp
+unit_signal_set_service_SOURCES = unit/signal_set_service.cpp
+unit_socket_acceptor_service_SOURCES = unit/socket_acceptor_service.cpp
+unit_socket_base_SOURCES = unit/socket_base.cpp
+unit_steady_timer_SOURCES = unit/steady_timer.cpp
+unit_strand_SOURCES = unit/strand.cpp
+unit_stream_socket_service_SOURCES = unit/stream_socket_service.cpp
+unit_streambuf_SOURCES = unit/streambuf.cpp
+unit_system_timer_SOURCES = unit/system_timer.cpp
+unit_thread_SOURCES = unit/thread.cpp
+unit_time_traits_SOURCES = unit/time_traits.cpp
+unit_use_future_SOURCES = unit/use_future.cpp
+unit_uses_executor_SOURCES = unit/uses_executor.cpp
+unit_wait_traits_SOURCES = unit/wait_traits.cpp
+unit_waitable_timer_service_SOURCES = unit/waitable_timer_service.cpp
+unit_windows_basic_handle_SOURCES = unit/windows/basic_handle.cpp
+unit_windows_basic_object_handle_SOURCES = unit/windows/basic_object_handle.cpp
+unit_windows_basic_random_access_handle_SOURCES = unit/windows/basic_random_access_handle.cpp
+unit_windows_basic_stream_handle_SOURCES = unit/windows/basic_stream_handle.cpp
+unit_windows_object_handle_SOURCES = unit/windows/object_handle.cpp
+unit_windows_object_handle_service_SOURCES = unit/windows/object_handle_service.cpp
+unit_windows_overlapped_handle_SOURCES = unit/windows/overlapped_handle.cpp
+unit_windows_overlapped_ptr_SOURCES = unit/windows/overlapped_ptr.cpp
+unit_windows_random_access_handle_SOURCES = unit/windows/random_access_handle.cpp
+unit_windows_random_access_handle_service_SOURCES = unit/windows/random_access_handle_service.cpp
+unit_windows_stream_handle_SOURCES = unit/windows/stream_handle.cpp
+unit_windows_stream_handle_service_SOURCES = unit/windows/stream_handle_service.cpp
+unit_write_SOURCES = unit/write.cpp
+unit_write_at_SOURCES = unit/write_at.cpp
+
+if HAVE_OPENSSL
+unit_ssl_context_base_SOURCES = unit/ssl/context_base.cpp
+unit_ssl_context_SOURCES = unit/ssl/context.cpp
+unit_ssl_stream_base_SOURCES = unit/ssl/stream_base.cpp
+unit_ssl_rfc2818_verification_SOURCES = unit/ssl/rfc2818_verification.cpp
+unit_ssl_stream_SOURCES = unit/ssl/stream.cpp
+endif
+
+EXTRA_DIST = \
+ latency/allocator.hpp \
+ performance/handler_allocator.hpp \
+ unit/archetypes/async_ops.hpp \
+ unit/archetypes/async_result.hpp \
+ unit/archetypes/deprecated_async_result.hpp \
+ unit/archetypes/deprecated_async_ops.hpp \
+ unit/archetypes/gettable_socket_option.hpp \
+ unit/archetypes/io_control_command.hpp \
+ unit/archetypes/settable_socket_option.hpp
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
diff --git a/3rdparty/asio/src/tests/latency/.gitignore b/3rdparty/asio/src/tests/latency/.gitignore
new file mode 100644
index 00000000000..feea55d4d7f
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*client
+*server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/tests/latency/allocator.hpp b/3rdparty/asio/src/tests/latency/allocator.hpp
new file mode 100644
index 00000000000..56a7af3ae9b
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/allocator.hpp
@@ -0,0 +1,52 @@
+//
+// allocator.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ALLOCATOR_HPP
+#define ALLOCATOR_HPP
+
+#include <boost/aligned_storage.hpp>
+
+// Represents a single connection from a client.
+class allocator
+{
+public:
+ allocator()
+ : in_use_(false)
+ {
+ }
+
+ void* allocate(std::size_t n)
+ {
+ if (in_use_ || n >= 1024)
+ return ::operator new(n);
+ in_use_ = true;
+ return static_cast<void*>(&space_);
+ }
+
+ void deallocate(void* p)
+ {
+ if (p != static_cast<void*>(&space_))
+ ::operator delete(p);
+ else
+ in_use_ = false;
+ }
+
+private:
+ allocator(const allocator&);
+ allocator& operator=(const allocator&);
+
+ // Whether the reusable memory space is currently in use.
+ bool in_use_;
+
+ // The reusable memory space made available by the allocator.
+ boost::aligned_storage<1024>::type space_;
+};
+
+#endif // ALLOCATOR_HPP
diff --git a/3rdparty/asio/src/tests/latency/coroutine.hpp b/3rdparty/asio/src/tests/latency/coroutine.hpp
new file mode 100644
index 00000000000..74b515b843c
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/coroutine.hpp
@@ -0,0 +1,87 @@
+//
+// coroutine.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 COROUTINE_HPP
+#define COROUTINE_HPP
+
+class coroutine
+{
+public:
+ coroutine() : value_(0) {}
+ bool is_child() const { return value_ < 0; }
+ bool is_parent() const { return !is_child(); }
+ bool is_complete() const { return value_ == -1; }
+private:
+ friend class coroutine_ref;
+ int value_;
+};
+
+class coroutine_ref
+{
+public:
+ coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
+ coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
+ ~coroutine_ref() { if (!modified_) value_ = -1; }
+ operator int() const { return value_; }
+ int& operator=(int v) { modified_ = true; return value_ = v; }
+private:
+ void operator=(const coroutine_ref&);
+ int& value_;
+ bool modified_;
+};
+
+#define CORO_REENTER(c) \
+ switch (coroutine_ref _coro_value = c) \
+ case -1: if (_coro_value) \
+ { \
+ goto terminate_coroutine; \
+ terminate_coroutine: \
+ _coro_value = -1; \
+ goto bail_out_of_coroutine; \
+ bail_out_of_coroutine: \
+ break; \
+ } \
+ else case 0:
+
+#define CORO_YIELD_IMPL(n) \
+ for (_coro_value = (n);;) \
+ if (_coro_value == 0) \
+ { \
+ case (n): ; \
+ break; \
+ } \
+ else \
+ switch (_coro_value ? 0 : 1) \
+ for (;;) \
+ case -1: if (_coro_value) \
+ goto terminate_coroutine; \
+ else for (;;) \
+ case 1: if (_coro_value) \
+ goto bail_out_of_coroutine; \
+ else case 0:
+
+#define CORO_FORK_IMPL(n) \
+ for (_coro_value = -(n);; _coro_value = (n)) \
+ if (_coro_value == (n)) \
+ { \
+ case -(n): ; \
+ break; \
+ } \
+ else
+
+#if defined(_MSC_VER)
+# define CORO_YIELD CORO_YIELD_IMPL(__COUNTER__ + 1)
+# define CORO_FORK CORO_FORK_IMPL(__COUNTER__ + 1)
+#else // defined(_MSC_VER)
+# define CORO_YIELD CORO_YIELD_IMPL(__LINE__)
+# define CORO_FORK CORO_FORK_IMPL(__LINE__)
+#endif // defined(_MSC_VER)
+
+#endif // COROUTINE_HPP
diff --git a/3rdparty/asio/src/tests/latency/high_res_clock.hpp b/3rdparty/asio/src/tests/latency/high_res_clock.hpp
new file mode 100644
index 00000000000..4756f52646b
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/high_res_clock.hpp
@@ -0,0 +1,53 @@
+//
+// high_res_clock.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HIGH_RES_CLOCK_HPP
+#define HIGH_RES_CLOCK_HPP
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+
+#if defined(ASIO_WINDOWS)
+
+inline boost::uint64_t high_res_clock()
+{
+ LARGE_INTEGER i;
+ QueryPerformanceCounter(&i);
+ return i.QuadPart;
+}
+
+#elif defined(__GNUC__) && defined(__x86_64__)
+
+inline boost::uint64_t high_res_clock()
+{
+ unsigned long low, high;
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
+ return (((boost::uint64_t)high) << 32) | low;
+}
+
+#else
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+inline boost::uint64_t high_res_clock()
+{
+ boost::posix_time::ptime now =
+ boost::posix_time::microsec_clock::universal_time();
+
+ boost::posix_time::ptime epoch(
+ boost::gregorian::date(1970, 1, 1),
+ boost::posix_time::seconds(0));
+
+ return (now - epoch).total_microseconds();
+}
+
+#endif
+
+#endif // HIGH_RES_CLOCK_HPP
diff --git a/3rdparty/asio/src/tests/latency/tcp_client.cpp b/3rdparty/asio/src/tests/latency/tcp_client.cpp
new file mode 100644
index 00000000000..ee1b6711f5d
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/tcp_client.cpp
@@ -0,0 +1,124 @@
+//
+// tcp_client.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/ip/tcp.hpp>
+#include <asio/read.hpp>
+#include <asio/write.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+#include "high_res_clock.hpp"
+
+using asio::ip::tcp;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+
+const int num_samples = 100000;
+
+struct transfer_all
+{
+ typedef std::size_t result_type;
+ std::size_t operator()(const asio::error_code& ec, std::size_t)
+ {
+ return (ec && ec != asio::error::would_block) ? 0 : ~0;
+ }
+};
+
+int main(int argc, char* argv[])
+{
+ if (argc != 6)
+ {
+ std::fprintf(stderr,
+ "Usage: tcp_client <ip> <port> "
+ "<nconns> <bufsize> {spin|block}\n");
+ return 1;
+ }
+
+ const char* ip = argv[1];
+ unsigned short port = static_cast<unsigned short>(std::atoi(argv[2]));
+ int num_connections = std::atoi(argv[3]);
+ std::size_t buf_size = static_cast<std::size_t>(std::atoi(argv[4]));
+ bool spin = (std::strcmp(argv[5], "spin") == 0);
+
+ asio::io_context io_context;
+ std::vector<boost::shared_ptr<tcp::socket> > sockets;
+
+ for (int i = 0; i < num_connections; ++i)
+ {
+ boost::shared_ptr<tcp::socket> s(new tcp::socket(io_context));
+
+ tcp::endpoint target(asio::ip::make_address(ip), port);
+ s->connect(target);
+
+ s->set_option(tcp::no_delay(true));
+
+ if (spin)
+ {
+ s->non_blocking(true);
+ }
+
+ sockets.push_back(s);
+ }
+
+ std::vector<unsigned char> write_buf(buf_size);
+ std::vector<unsigned char> read_buf(buf_size);
+
+ ptime start = microsec_clock::universal_time();
+ boost::uint64_t start_hr = high_res_clock();
+
+ boost::uint64_t samples[num_samples];
+ for (int i = 0; i < num_samples; ++i)
+ {
+ tcp::socket& socket = *sockets[i % num_connections];
+
+ boost::uint64_t t = high_res_clock();
+
+ asio::error_code ec;
+ asio::write(socket,
+ asio::buffer(write_buf),
+ transfer_all(), ec);
+
+ asio::read(socket,
+ asio::buffer(read_buf),
+ transfer_all(), ec);
+
+ samples[i] = high_res_clock() - t;
+ }
+
+ ptime stop = microsec_clock::universal_time();
+ boost::uint64_t stop_hr = high_res_clock();
+ boost::uint64_t elapsed_usec = (stop - start).total_microseconds();
+ boost::uint64_t elapsed_hr = stop_hr - start_hr;
+ double scale = 1.0 * elapsed_usec / elapsed_hr;
+
+ std::sort(samples, samples + num_samples);
+ std::printf(" 0.0%%\t%f\n", samples[0] * scale);
+ std::printf(" 0.1%%\t%f\n", samples[num_samples / 1000 - 1] * scale);
+ std::printf(" 1.0%%\t%f\n", samples[num_samples / 100 - 1] * scale);
+ std::printf(" 10.0%%\t%f\n", samples[num_samples / 10 - 1] * scale);
+ std::printf(" 20.0%%\t%f\n", samples[num_samples * 2 / 10 - 1] * scale);
+ std::printf(" 30.0%%\t%f\n", samples[num_samples * 3 / 10 - 1] * scale);
+ std::printf(" 40.0%%\t%f\n", samples[num_samples * 4 / 10 - 1] * scale);
+ std::printf(" 50.0%%\t%f\n", samples[num_samples * 5 / 10 - 1] * scale);
+ std::printf(" 60.0%%\t%f\n", samples[num_samples * 6 / 10 - 1] * scale);
+ std::printf(" 70.0%%\t%f\n", samples[num_samples * 7 / 10 - 1] * scale);
+ std::printf(" 80.0%%\t%f\n", samples[num_samples * 8 / 10 - 1] * scale);
+ std::printf(" 90.0%%\t%f\n", samples[num_samples * 9 / 10 - 1] * scale);
+ std::printf(" 99.0%%\t%f\n", samples[num_samples * 99 / 100 - 1] * scale);
+ std::printf(" 99.9%%\t%f\n", samples[num_samples * 999 / 1000 - 1] * scale);
+ std::printf("100.0%%\t%f\n", samples[num_samples - 1] * scale);
+
+ double total = 0.0;
+ for (int i = 0; i < num_samples; ++i) total += samples[i] * scale;
+ std::printf(" mean\t%f\n", total / num_samples);
+}
diff --git a/3rdparty/asio/src/tests/latency/tcp_server.cpp b/3rdparty/asio/src/tests/latency/tcp_server.cpp
new file mode 100644
index 00000000000..2bbdfdc17b0
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/tcp_server.cpp
@@ -0,0 +1,114 @@
+//
+// tcp_server.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/io_context.hpp>
+#include <asio/ip/tcp.hpp>
+#include <asio/read.hpp>
+#include <asio/write.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+
+using asio::ip::tcp;
+
+#include "yield.hpp"
+
+class tcp_server : coroutine
+{
+public:
+ tcp_server(tcp::acceptor& acceptor, std::size_t buf_size) :
+ acceptor_(acceptor),
+ socket_(acceptor_.get_executor().context()),
+ buffer_(buf_size)
+ {
+ }
+
+ void operator()(asio::error_code ec, std::size_t n = 0)
+ {
+ reenter (this) for (;;)
+ {
+ yield acceptor_.async_accept(socket_, ref(this));
+
+ while (!ec)
+ {
+ yield asio::async_read(socket_,
+ asio::buffer(buffer_), ref(this));
+
+ if (!ec)
+ {
+ for (std::size_t i = 0; i < n; ++i) buffer_[i] = ~buffer_[i];
+
+ yield asio::async_write(socket_,
+ asio::buffer(buffer_), ref(this));
+ }
+ }
+
+ socket_.close();
+ }
+ }
+
+ struct ref
+ {
+ explicit ref(tcp_server* p)
+ : p_(p)
+ {
+ }
+
+ void operator()(asio::error_code ec, std::size_t n = 0)
+ {
+ (*p_)(ec, n);
+ }
+
+ private:
+ tcp_server* p_;
+ };
+
+private:
+ tcp::acceptor& acceptor_;
+ tcp::socket socket_;
+ std::vector<unsigned char> buffer_;
+ tcp::endpoint sender_;
+};
+
+#include "unyield.hpp"
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ {
+ std::fprintf(stderr,
+ "Usage: tcp_server <port> <nconns> "
+ "<bufsize> {spin|block}\n");
+ return 1;
+ }
+
+ unsigned short port = static_cast<unsigned short>(std::atoi(argv[1]));
+ int max_connections = std::atoi(argv[2]);
+ std::size_t buf_size = std::atoi(argv[3]);
+ bool spin = (std::strcmp(argv[4], "spin") == 0);
+
+ asio::io_context io_context(1);
+ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
+ std::vector<boost::shared_ptr<tcp_server> > servers;
+
+ for (int i = 0; i < max_connections; ++i)
+ {
+ boost::shared_ptr<tcp_server> s(new tcp_server(acceptor, buf_size));
+ servers.push_back(s);
+ (*s)(asio::error_code());
+ }
+
+ if (spin)
+ for (;;) io_context.poll();
+ else
+ io_context.run();
+}
diff --git a/3rdparty/asio/src/tests/latency/udp_client.cpp b/3rdparty/asio/src/tests/latency/udp_client.cpp
new file mode 100644
index 00000000000..cc2762971d0
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/udp_client.cpp
@@ -0,0 +1,104 @@
+//
+// udp_client.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/ip/udp.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+#include "high_res_clock.hpp"
+
+using asio::ip::udp;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+
+const int num_samples = 100000;
+
+int main(int argc, char* argv[])
+{
+ if (argc != 6)
+ {
+ std::fprintf(stderr,
+ "Usage: udp_client <ip> <port1> "
+ "<nports> <bufsize> {spin|block}\n");
+ return 1;
+ }
+
+ const char* ip = argv[1];
+ unsigned short first_port = static_cast<unsigned short>(std::atoi(argv[2]));
+ unsigned short num_ports = static_cast<unsigned short>(std::atoi(argv[3]));
+ std::size_t buf_size = static_cast<std::size_t>(std::atoi(argv[4]));
+ bool spin = (std::strcmp(argv[5], "spin") == 0);
+
+ asio::io_context io_context;
+
+ udp::socket socket(io_context, udp::endpoint(udp::v4(), 0));
+
+ if (spin)
+ {
+ socket.non_blocking(true);
+ }
+
+ udp::endpoint target(asio::ip::make_address(ip), first_port);
+ unsigned short last_port = first_port + num_ports - 1;
+ std::vector<unsigned char> write_buf(buf_size);
+ std::vector<unsigned char> read_buf(buf_size);
+
+ ptime start = microsec_clock::universal_time();
+ boost::uint64_t start_hr = high_res_clock();
+
+ boost::uint64_t samples[num_samples];
+ for (int i = 0; i < num_samples; ++i)
+ {
+ boost::uint64_t t = high_res_clock();
+
+ asio::error_code ec;
+ socket.send_to(asio::buffer(write_buf), target, 0, ec);
+
+ do socket.receive(asio::buffer(read_buf), 0, ec);
+ while (ec == asio::error::would_block);
+
+ samples[i] = high_res_clock() - t;
+
+ if (target.port() == last_port)
+ target.port(first_port);
+ else
+ target.port(target.port() + 1);
+ }
+
+ ptime stop = microsec_clock::universal_time();
+ boost::uint64_t stop_hr = high_res_clock();
+ boost::uint64_t elapsed_usec = (stop - start).total_microseconds();
+ boost::uint64_t elapsed_hr = stop_hr - start_hr;
+ double scale = 1.0 * elapsed_usec / elapsed_hr;
+
+ std::sort(samples, samples + num_samples);
+ std::printf(" 0.0%%\t%f\n", samples[0] * scale);
+ std::printf(" 0.1%%\t%f\n", samples[num_samples / 1000 - 1] * scale);
+ std::printf(" 1.0%%\t%f\n", samples[num_samples / 100 - 1] * scale);
+ std::printf(" 10.0%%\t%f\n", samples[num_samples / 10 - 1] * scale);
+ std::printf(" 20.0%%\t%f\n", samples[num_samples * 2 / 10 - 1] * scale);
+ std::printf(" 30.0%%\t%f\n", samples[num_samples * 3 / 10 - 1] * scale);
+ std::printf(" 40.0%%\t%f\n", samples[num_samples * 4 / 10 - 1] * scale);
+ std::printf(" 50.0%%\t%f\n", samples[num_samples * 5 / 10 - 1] * scale);
+ std::printf(" 60.0%%\t%f\n", samples[num_samples * 6 / 10 - 1] * scale);
+ std::printf(" 70.0%%\t%f\n", samples[num_samples * 7 / 10 - 1] * scale);
+ std::printf(" 80.0%%\t%f\n", samples[num_samples * 8 / 10 - 1] * scale);
+ std::printf(" 90.0%%\t%f\n", samples[num_samples * 9 / 10 - 1] * scale);
+ std::printf(" 99.0%%\t%f\n", samples[num_samples * 99 / 100 - 1] * scale);
+ std::printf(" 99.9%%\t%f\n", samples[num_samples * 999 / 1000 - 1] * scale);
+ std::printf("100.0%%\t%f\n", samples[num_samples - 1] * scale);
+
+ double total = 0.0;
+ for (int i = 0; i < num_samples; ++i) total += samples[i] * scale;
+ std::printf(" mean\t%f\n", total / num_samples);
+}
diff --git a/3rdparty/asio/src/tests/latency/udp_server.cpp b/3rdparty/asio/src/tests/latency/udp_server.cpp
new file mode 100644
index 00000000000..a767f4c782a
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/udp_server.cpp
@@ -0,0 +1,125 @@
+//
+// udp_server.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include <asio/io_context.hpp>
+#include <asio/ip/udp.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+#include "allocator.hpp"
+
+using asio::ip::udp;
+
+#include "yield.hpp"
+
+class udp_server : coroutine
+{
+public:
+ udp_server(asio::io_context& io_context,
+ unsigned short port, std::size_t buf_size) :
+ socket_(io_context, udp::endpoint(udp::v4(), port)),
+ buffer_(buf_size)
+ {
+ }
+
+ void operator()(asio::error_code ec, std::size_t n = 0)
+ {
+ reenter (this) for (;;)
+ {
+ yield socket_.async_receive_from(
+ asio::buffer(buffer_),
+ sender_, ref(this));
+
+ if (!ec)
+ {
+ for (std::size_t i = 0; i < n; ++i) buffer_[i] = ~buffer_[i];
+ socket_.send_to(asio::buffer(buffer_, n), sender_, 0, ec);
+ }
+ }
+ }
+
+ friend void* asio_handler_allocate(std::size_t n, udp_server* s)
+ {
+ return s->allocator_.allocate(n);
+ }
+
+ friend void asio_handler_deallocate(void* p, std::size_t, udp_server* s)
+ {
+ s->allocator_.deallocate(p);
+ }
+
+ struct ref
+ {
+ explicit ref(udp_server* p)
+ : p_(p)
+ {
+ }
+
+ void operator()(asio::error_code ec, std::size_t n = 0)
+ {
+ (*p_)(ec, n);
+ }
+
+ private:
+ udp_server* p_;
+
+ friend void* asio_handler_allocate(std::size_t n, ref* r)
+ {
+ return asio_handler_allocate(n, r->p_);
+ }
+
+ friend void asio_handler_deallocate(void* p, std::size_t n, ref* r)
+ {
+ asio_handler_deallocate(p, n, r->p_);
+ }
+ };
+
+private:
+ udp::socket socket_;
+ std::vector<unsigned char> buffer_;
+ udp::endpoint sender_;
+ allocator allocator_;
+};
+
+#include "unyield.hpp"
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ {
+ std::fprintf(stderr,
+ "Usage: udp_server <port1> <nports> "
+ "<bufsize> {spin|block}\n");
+ return 1;
+ }
+
+ unsigned short first_port = static_cast<unsigned short>(std::atoi(argv[1]));
+ unsigned short num_ports = static_cast<unsigned short>(std::atoi(argv[2]));
+ std::size_t buf_size = std::atoi(argv[3]);
+ bool spin = (std::strcmp(argv[4], "spin") == 0);
+
+ asio::io_context io_context(1);
+ std::vector<boost::shared_ptr<udp_server> > servers;
+
+ for (unsigned short i = 0; i < num_ports; ++i)
+ {
+ unsigned short port = first_port + i;
+ boost::shared_ptr<udp_server> s(new udp_server(io_context, port, buf_size));
+ servers.push_back(s);
+ (*s)(asio::error_code());
+ }
+
+ if (spin)
+ for (;;) io_context.poll();
+ else
+ io_context.run();
+}
diff --git a/3rdparty/asio/src/tests/latency/unyield.hpp b/3rdparty/asio/src/tests/latency/unyield.hpp
new file mode 100644
index 00000000000..ccbb043547e
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/unyield.hpp
@@ -0,0 +1,21 @@
+//
+// unyield.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#ifdef reenter
+# undef reenter
+#endif
+
+#ifdef yield
+# undef yield
+#endif
+
+#ifdef fork
+# undef fork
+#endif
diff --git a/3rdparty/asio/src/tests/latency/yield.hpp b/3rdparty/asio/src/tests/latency/yield.hpp
new file mode 100644
index 00000000000..bf4c6a8e13e
--- /dev/null
+++ b/3rdparty/asio/src/tests/latency/yield.hpp
@@ -0,0 +1,23 @@
+//
+// yield.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "coroutine.hpp"
+
+#ifndef reenter
+# define reenter(c) CORO_REENTER(c)
+#endif
+
+#ifndef yield
+# define yield CORO_YIELD
+#endif
+
+#ifndef fork
+# define fork CORO_FORK
+#endif
diff --git a/3rdparty/asio/src/tests/performance/.gitignore b/3rdparty/asio/src/tests/performance/.gitignore
new file mode 100644
index 00000000000..692ea7e7e65
--- /dev/null
+++ b/3rdparty/asio/src/tests/performance/.gitignore
@@ -0,0 +1,11 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+client
+server
+*.ilk
+*.manifest
+*.pdb
+*.tds
diff --git a/3rdparty/asio/src/tests/performance/client.cpp b/3rdparty/asio/src/tests/performance/client.cpp
new file mode 100644
index 00000000000..6851d32fc9e
--- /dev/null
+++ b/3rdparty/asio/src/tests/performance/client.cpp
@@ -0,0 +1,286 @@
+//
+// client.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio.hpp"
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <boost/mem_fn.hpp>
+#include <iostream>
+#include <list>
+#include <string>
+#include "handler_allocator.hpp"
+
+class stats
+{
+public:
+ stats()
+ : mutex_(),
+ total_bytes_written_(0),
+ total_bytes_read_(0)
+ {
+ }
+
+ void add(size_t bytes_written, size_t bytes_read)
+ {
+ asio::detail::mutex::scoped_lock lock(mutex_);
+ total_bytes_written_ += bytes_written;
+ total_bytes_read_ += bytes_read;
+ }
+
+ void print()
+ {
+ asio::detail::mutex::scoped_lock lock(mutex_);
+ std::cout << total_bytes_written_ << " total bytes written\n";
+ std::cout << total_bytes_read_ << " total bytes read\n";
+ }
+
+private:
+ asio::detail::mutex mutex_;
+ size_t total_bytes_written_;
+ size_t total_bytes_read_;
+};
+
+class session
+{
+public:
+ session(asio::io_context& ioc, size_t block_size, stats& s)
+ : strand_(ioc),
+ socket_(ioc),
+ block_size_(block_size),
+ read_data_(new char[block_size]),
+ read_data_length_(0),
+ write_data_(new char[block_size]),
+ unwritten_count_(0),
+ bytes_written_(0),
+ bytes_read_(0),
+ stats_(s)
+ {
+ for (size_t i = 0; i < block_size_; ++i)
+ write_data_[i] = static_cast<char>(i % 128);
+ }
+
+ ~session()
+ {
+ stats_.add(bytes_written_, bytes_read_);
+
+ delete[] read_data_;
+ delete[] write_data_;
+ }
+
+ void start(asio::ip::tcp::resolver::results_type endpoints)
+ {
+ asio::async_connect(socket_, endpoints,
+ asio::bind_executor(strand_,
+ boost::bind(&session::handle_connect, this,
+ asio::placeholders::error)));
+ }
+
+ void stop()
+ {
+ asio::post(strand_, boost::bind(&session::close_socket, this));
+ }
+
+private:
+ void handle_connect(const asio::error_code& err)
+ {
+ if (!err)
+ {
+ asio::error_code set_option_err;
+ asio::ip::tcp::no_delay no_delay(true);
+ socket_.set_option(no_delay, set_option_err);
+ if (!set_option_err)
+ {
+ ++unwritten_count_;
+ async_write(socket_, asio::buffer(write_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(write_allocator_,
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ }
+ }
+
+ void handle_read(const asio::error_code& err, size_t length)
+ {
+ if (!err)
+ {
+ bytes_read_ += length;
+
+ read_data_length_ = length;
+ ++unwritten_count_;
+ if (unwritten_count_ == 1)
+ {
+ std::swap(read_data_, write_data_);
+ async_write(socket_, asio::buffer(write_data_, read_data_length_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(write_allocator_,
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ }
+ }
+
+ void handle_write(const asio::error_code& err, size_t length)
+ {
+ if (!err && length > 0)
+ {
+ bytes_written_ += length;
+
+ --unwritten_count_;
+ if (unwritten_count_ == 1)
+ {
+ std::swap(read_data_, write_data_);
+ async_write(socket_, asio::buffer(write_data_, read_data_length_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(write_allocator_,
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ }
+ }
+
+ void close_socket()
+ {
+ socket_.close();
+ }
+
+private:
+ asio::io_context::strand strand_;
+ asio::ip::tcp::socket socket_;
+ size_t block_size_;
+ char* read_data_;
+ size_t read_data_length_;
+ char* write_data_;
+ int unwritten_count_;
+ size_t bytes_written_;
+ size_t bytes_read_;
+ stats& stats_;
+ handler_allocator read_allocator_;
+ handler_allocator write_allocator_;
+};
+
+class client
+{
+public:
+ client(asio::io_context& ioc,
+ const asio::ip::tcp::resolver::results_type endpoints,
+ size_t block_size, size_t session_count, int timeout)
+ : io_context_(ioc),
+ stop_timer_(ioc),
+ sessions_(),
+ stats_()
+ {
+ stop_timer_.expires_from_now(boost::posix_time::seconds(timeout));
+ stop_timer_.async_wait(boost::bind(&client::handle_timeout, this));
+
+ for (size_t i = 0; i < session_count; ++i)
+ {
+ session* new_session = new session(io_context_, block_size, stats_);
+ new_session->start(endpoints);
+ sessions_.push_back(new_session);
+ }
+ }
+
+ ~client()
+ {
+ while (!sessions_.empty())
+ {
+ delete sessions_.front();
+ sessions_.pop_front();
+ }
+
+ stats_.print();
+ }
+
+ void handle_timeout()
+ {
+ std::for_each(sessions_.begin(), sessions_.end(),
+ boost::mem_fn(&session::stop));
+ }
+
+private:
+ asio::io_context& io_context_;
+ asio::deadline_timer stop_timer_;
+ std::list<session*> sessions_;
+ stats stats_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 7)
+ {
+ std::cerr << "Usage: client <host> <port> <threads> <blocksize> ";
+ std::cerr << "<sessions> <time>\n";
+ return 1;
+ }
+
+ using namespace std; // For atoi.
+ const char* host = argv[1];
+ const char* port = argv[2];
+ int thread_count = atoi(argv[3]);
+ size_t block_size = atoi(argv[4]);
+ size_t session_count = atoi(argv[5]);
+ int timeout = atoi(argv[6]);
+
+ asio::io_context ioc;
+
+ asio::ip::tcp::resolver r(ioc);
+ asio::ip::tcp::resolver::results_type endpoints =
+ r.resolve(host, port);
+
+ client c(ioc, endpoints, block_size, session_count, timeout);
+
+ std::list<asio::thread*> threads;
+ while (--thread_count > 0)
+ {
+ asio::thread* new_thread = new asio::thread(
+ boost::bind(&asio::io_context::run, &ioc));
+ threads.push_back(new_thread);
+ }
+
+ ioc.run();
+
+ while (!threads.empty())
+ {
+ threads.front()->join();
+ delete threads.front();
+ threads.pop_front();
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/tests/performance/handler_allocator.hpp b/3rdparty/asio/src/tests/performance/handler_allocator.hpp
new file mode 100644
index 00000000000..b8609049728
--- /dev/null
+++ b/3rdparty/asio/src/tests/performance/handler_allocator.hpp
@@ -0,0 +1,112 @@
+//
+// handler_allocator.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 HANDLER_ALLOCATOR_HPP
+#define HANDLER_ALLOCATOR_HPP
+
+#include "asio.hpp"
+#include <boost/aligned_storage.hpp>
+#include <boost/noncopyable.hpp>
+
+// Class to manage the memory to be used for handler-based custom allocation.
+// It contains a single block of memory which may be returned for allocation
+// requests. If the memory is in use when an allocation request is made, the
+// allocator delegates allocation to the global heap.
+class handler_allocator
+ : private boost::noncopyable
+{
+public:
+ handler_allocator()
+ : in_use_(false)
+ {
+ }
+
+ void* allocate(std::size_t size)
+ {
+ if (!in_use_ && size < storage_.size)
+ {
+ in_use_ = true;
+ return storage_.address();
+ }
+
+ return ::operator new(size);
+ }
+
+ void deallocate(void* pointer)
+ {
+ if (pointer == storage_.address())
+ {
+ in_use_ = false;
+ }
+ else
+ {
+ ::operator delete(pointer);
+ }
+ }
+
+private:
+ // Storage space used for handler-based custom memory allocation.
+ boost::aligned_storage<1024> storage_;
+
+ // Whether the handler-based custom allocation storage has been used.
+ bool in_use_;
+};
+
+// Wrapper class template for handler objects to allow handler memory
+// allocation to be customised. Calls to operator() are forwarded to the
+// encapsulated handler.
+template <typename Handler>
+class custom_alloc_handler
+{
+public:
+ custom_alloc_handler(handler_allocator& a, Handler h)
+ : allocator_(a),
+ handler_(h)
+ {
+ }
+
+ template <typename Arg1>
+ void operator()(Arg1 arg1)
+ {
+ handler_(arg1);
+ }
+
+ template <typename Arg1, typename Arg2>
+ void operator()(Arg1 arg1, Arg2 arg2)
+ {
+ handler_(arg1, arg2);
+ }
+
+ friend void* asio_handler_allocate(std::size_t size,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ return this_handler->allocator_.allocate(size);
+ }
+
+ friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
+ custom_alloc_handler<Handler>* this_handler)
+ {
+ this_handler->allocator_.deallocate(pointer);
+ }
+
+private:
+ handler_allocator& allocator_;
+ Handler handler_;
+};
+
+// Helper function to wrap a handler object to add custom allocation.
+template <typename Handler>
+inline custom_alloc_handler<Handler> make_custom_alloc_handler(
+ handler_allocator& a, Handler h)
+{
+ return custom_alloc_handler<Handler>(a, h);
+}
+
+#endif // HANDLER_ALLOCATOR_HPP
diff --git a/3rdparty/asio/src/tests/performance/server.cpp b/3rdparty/asio/src/tests/performance/server.cpp
new file mode 100644
index 00000000000..be8c3813ece
--- /dev/null
+++ b/3rdparty/asio/src/tests/performance/server.cpp
@@ -0,0 +1,233 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+#include "asio.hpp"
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <iostream>
+#include <list>
+#include "handler_allocator.hpp"
+
+class session
+{
+public:
+ session(asio::io_context& ioc, size_t block_size)
+ : io_context_(ioc),
+ strand_(ioc),
+ socket_(ioc),
+ block_size_(block_size),
+ read_data_(new char[block_size]),
+ read_data_length_(0),
+ write_data_(new char[block_size]),
+ unsent_count_(0),
+ op_count_(0)
+ {
+ }
+
+ ~session()
+ {
+ delete[] read_data_;
+ delete[] write_data_;
+ }
+
+ asio::ip::tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start()
+ {
+ asio::error_code set_option_err;
+ asio::ip::tcp::no_delay no_delay(true);
+ socket_.set_option(no_delay, set_option_err);
+ if (!set_option_err)
+ {
+ ++op_count_;
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ else
+ {
+ asio::post(io_context_, boost::bind(&session::destroy, this));
+ }
+ }
+
+ void handle_read(const asio::error_code& err, size_t length)
+ {
+ --op_count_;
+
+ if (!err)
+ {
+ read_data_length_ = length;
+ ++unsent_count_;
+ if (unsent_count_ == 1)
+ {
+ op_count_ += 2;
+ std::swap(read_data_, write_data_);
+ async_write(socket_, asio::buffer(write_data_, read_data_length_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(write_allocator_,
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error))));
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ }
+
+ if (op_count_ == 0)
+ asio::post(io_context_, boost::bind(&session::destroy, this));
+ }
+
+ void handle_write(const asio::error_code& err)
+ {
+ --op_count_;
+
+ if (!err)
+ {
+ --unsent_count_;
+ if (unsent_count_ == 1)
+ {
+ op_count_ += 2;
+ std::swap(read_data_, write_data_);
+ async_write(socket_, asio::buffer(write_data_, read_data_length_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(write_allocator_,
+ boost::bind(&session::handle_write, this,
+ asio::placeholders::error))));
+ socket_.async_read_some(asio::buffer(read_data_, block_size_),
+ asio::bind_executor(strand_,
+ make_custom_alloc_handler(read_allocator_,
+ boost::bind(&session::handle_read, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred))));
+ }
+ }
+
+ if (op_count_ == 0)
+ asio::post(io_context_, boost::bind(&session::destroy, this));
+ }
+
+ static void destroy(session* s)
+ {
+ delete s;
+ }
+
+private:
+ asio::io_context& io_context_;
+ asio::io_context::strand strand_;
+ asio::ip::tcp::socket socket_;
+ size_t block_size_;
+ char* read_data_;
+ size_t read_data_length_;
+ char* write_data_;
+ int unsent_count_;
+ int op_count_;
+ handler_allocator read_allocator_;
+ handler_allocator write_allocator_;
+};
+
+class server
+{
+public:
+ server(asio::io_context& ioc, const asio::ip::tcp::endpoint& endpoint,
+ size_t block_size)
+ : io_context_(ioc),
+ acceptor_(ioc),
+ block_size_(block_size)
+ {
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(1));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ start_accept();
+ }
+
+ void start_accept()
+ {
+ session* new_session = new session(io_context_, block_size_);
+ acceptor_.async_accept(new_session->socket(),
+ boost::bind(&server::handle_accept, this, new_session,
+ asio::placeholders::error));
+ }
+
+ void handle_accept(session* new_session, const asio::error_code& err)
+ {
+ if (!err)
+ {
+ new_session->start();
+ }
+ else
+ {
+ delete new_session;
+ }
+
+ start_accept();
+ }
+
+private:
+ asio::io_context& io_context_;
+ asio::ip::tcp::acceptor acceptor_;
+ size_t block_size_;
+};
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ if (argc != 5)
+ {
+ std::cerr << "Usage: server <address> <port> <threads> <blocksize>\n";
+ return 1;
+ }
+
+ using namespace std; // For atoi.
+ asio::ip::address address = asio::ip::make_address(argv[1]);
+ short port = atoi(argv[2]);
+ int thread_count = atoi(argv[3]);
+ size_t block_size = atoi(argv[4]);
+
+ asio::io_context ioc;
+
+ server s(ioc, asio::ip::tcp::endpoint(address, port), block_size);
+
+ // Threads not currently supported in this test.
+ std::list<asio::thread*> threads;
+ while (--thread_count > 0)
+ {
+ asio::thread* new_thread = new asio::thread(
+ boost::bind(&asio::io_context::run, &ioc));
+ threads.push_back(new_thread);
+ }
+
+ ioc.run();
+
+ while (!threads.empty())
+ {
+ threads.front()->join();
+ delete threads.front();
+ threads.pop_front();
+ }
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << "\n";
+ }
+
+ return 0;
+}
diff --git a/3rdparty/asio/src/tests/unit/.gitignore b/3rdparty/asio/src/tests/unit/.gitignore
new file mode 100644
index 00000000000..e11b5d56f36
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/.gitignore
@@ -0,0 +1,74 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+associated_allocator
+associated_executor
+async_result
+basic_datagram_socket
+basic_deadline_timer
+basic_raw_socket
+basic_seq_packet_socket
+basic_serial_port
+basic_signal_set
+basic_socket_acceptor
+basic_stream_socket
+basic_streambuf
+basic_waitable_timer
+bind_executor
+buffer
+buffered_read_stream
+buffered_stream
+buffered_write_stream
+buffers_iterator
+completion_condition
+connect
+coroutine
+datagram_socket_service
+deadline_timer
+deadline_timer_service
+defer
+dispatch
+error
+error_handler
+execution_context
+executor
+executor_work_guard
+high_resolution_timer
+io_context
+io_service
+is_read_buffered
+is_write_buffered
+packaged_task
+placeholders
+post
+raw_socket_service
+read
+read_at
+read_until
+seq_packet_socket_service
+serial_port
+serial_port_base
+serial_port_service
+signal_set
+signal_set_service
+socket_acceptor_service
+socket_base
+steady_timer
+strand
+stream_socket_service
+streambuf
+system_timer
+thread
+time_traits
+use_future
+uses_executor
+wait_traits
+waitable_timer_service
+write
+write_at
diff --git a/3rdparty/asio/src/tests/unit/archetypes/async_ops.hpp b/3rdparty/asio/src/tests/unit/archetypes/async_ops.hpp
new file mode 100644
index 00000000000..331d8ac32ef
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/async_ops.hpp
@@ -0,0 +1,415 @@
+//
+// async_ops.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_ASYNC_OPS_HPP
+#define ARCHETYPES_ASYNC_OPS_HPP
+
+#include <asio/associated_allocator.hpp>
+#include <asio/associated_executor.hpp>
+#include <asio/async_result.hpp>
+#include <asio/error.hpp>
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+namespace archetypes {
+
+#if defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = std;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void())
+async_op_0(ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void()>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void()> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ ex.post(ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(asio::error_code))
+async_op_ec_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(asio::error_code)>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(asio::error_code)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code()), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(asio::error::operation_aborted)), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr))
+async_op_ex_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(std::exception_ptr)>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(std::exception_ptr)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::exception_ptr()), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::make_exception_ptr(std::runtime_error("blah"))), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))
+async_op_1(ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(int)>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(int)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ 42), a);
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ void(asio::error_code, int))
+async_op_ec_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(asio::error_code, int)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(asio::error_code, int)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(), 42), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(asio::error::operation_aborted),
+ 0), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr, int))
+async_op_ex_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::exception_ptr(), 42), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::make_exception_ptr(std::runtime_error("blah")), 0), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double))
+async_op_2(ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(int, double)>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(int, double)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ 42, 2.0), a);
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ void(asio::error_code, int, double))
+async_op_ec_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(asio::error_code, int, double)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(asio::error_code, int, double)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(), 42, 2.0), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(asio::error::operation_aborted),
+ 0, 0.0), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ void(std::exception_ptr, int, double))
+async_op_ex_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int, double)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int, double)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::exception_ptr(), 42, 2.0), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double, char))
+async_op_3(ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(int, double, char)>::completion_handler_type handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(int, double, char)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ 42, 2.0, 'a'), a);
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ void(asio::error_code, int, double, char))
+async_op_ec_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(asio::error_code, int, double, char)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(asio::error_code, int, double, char)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(), 42, 2.0, 'a'), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ asio::error_code(asio::error::operation_aborted),
+ 0, 0.0, 'z'), a);
+ }
+
+ return completion.result.get();
+}
+
+template <typename CompletionToken>
+ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ void(std::exception_ptr, int, double, char))
+async_op_ex_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int, double, char)>::completion_handler_type
+ handler_type;
+
+ asio::async_completion<CompletionToken,
+ void(std::exception_ptr, int, double, char)> completion(token);
+
+ typename asio::associated_allocator<handler_type>::type a
+ = asio::get_associated_allocator(completion.completion_handler);
+
+ typename asio::associated_executor<handler_type>::type ex
+ = asio::get_associated_executor(completion.completion_handler);
+
+ if (ok)
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::exception_ptr(), 42, 2.0, 'a'), a);
+ }
+ else
+ {
+ ex.post(
+ bindns::bind(
+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
+ std::make_exception_ptr(std::runtime_error("blah")),
+ 0, 0.0, 'z'), a);
+ }
+
+ return completion.result.get();
+}
+
+} // namespace archetypes
+
+#endif // ARCHETYPES_ASYNC_OPS_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/async_result.hpp b/3rdparty/asio/src/tests/unit/archetypes/async_result.hpp
new file mode 100644
index 00000000000..afd9e56f191
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/async_result.hpp
@@ -0,0 +1,78 @@
+//
+// async_result.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_ASYNC_RESULT_HPP
+#define ARCHETYPES_ASYNC_RESULT_HPP
+
+#include <asio/async_result.hpp>
+
+namespace archetypes {
+
+struct lazy_handler
+{
+};
+
+struct concrete_handler
+{
+ concrete_handler(lazy_handler)
+ {
+ }
+
+ template <typename Arg1>
+ void operator()(Arg1)
+ {
+ }
+
+ template <typename Arg1, typename Arg2>
+ void operator()(Arg1, Arg2)
+ {
+ }
+
+#if defined(ASIO_HAS_MOVE)
+ concrete_handler(concrete_handler&&) {}
+private:
+ concrete_handler(const concrete_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+} // namespace archetypes
+
+namespace asio {
+
+template <typename Signature>
+class async_result<archetypes::lazy_handler, Signature>
+{
+public:
+ // The concrete completion handler type.
+ typedef archetypes::concrete_handler completion_handler_type;
+
+ // The return type of the initiating function.
+ typedef int return_type;
+
+ // Construct an async_result from a given handler.
+ explicit async_result(completion_handler_type&)
+ {
+ }
+
+ // Obtain the value to be returned from the initiating function.
+ return_type get()
+ {
+ return 42;
+ }
+
+private:
+ // Disallow copying and assignment.
+ async_result(const async_result&) ASIO_DELETED;
+ async_result& operator=(const async_result&) ASIO_DELETED;
+};
+
+} // namespace asio
+
+#endif // ARCHETYPES_ASYNC_RESULT_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_ops.hpp b/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_ops.hpp
new file mode 100644
index 00000000000..ee1cab939cd
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_ops.hpp
@@ -0,0 +1,345 @@
+//
+// deprecated_async_ops.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_DEPRECATED_ASYNC_OPS_HPP
+#define ARCHETYPES_DEPRECATED_ASYNC_OPS_HPP
+
+#include <asio/async_result.hpp>
+
+#if !defined(ASIO_NO_DEPRECATED)
+
+#include <asio/handler_type.hpp>
+#include <asio/error.hpp>
+#include <asio/io_context.hpp>
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+namespace archetypes {
+
+#if defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = std;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void()>::type>::type
+deprecated_async_op_0(asio::io_context& ctx,
+ ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void()>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler)));
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(asio::error_code)>::type>::type
+deprecated_async_op_ec_0(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(asio::error_code)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code()));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(asio::error::operation_aborted)));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr)>::type>::type
+deprecated_async_op_ex_0(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::exception_ptr()));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::make_exception_ptr(std::runtime_error("blah"))));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(int)>::type>::type
+deprecated_async_op_1(asio::io_context& ctx,
+ ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(int)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler), 42));
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int)>::type>::type
+deprecated_async_op_ec_1(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(), 42));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(asio::error::operation_aborted), 0));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int)>::type>::type
+deprecated_async_op_ex_1(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::exception_ptr(), 42));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::make_exception_ptr(std::runtime_error("blah")), 0));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(int, double)>::type>::type
+deprecated_async_op_2(asio::io_context& ctx,
+ ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(int, double)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ 42, 2.0));
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int, double)>::type>::type
+deprecated_async_op_ec_2(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int, double)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(), 42, 2.0));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(asio::error::operation_aborted),
+ 0, 0.0));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int, double)>::type>::type
+deprecated_async_op_ex_2(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int, double)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::exception_ptr(), 42, 2.0));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(int, double, char)>::type>::type
+deprecated_async_op_3(asio::io_context& ctx,
+ ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(int, double, char)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ 42, 2.0, 'a'));
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int, double, char)>::type>::type
+deprecated_async_op_ec_3(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(asio::error_code, int, double, char)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(), 42, 2.0, 'a'));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ asio::error_code(asio::error::operation_aborted),
+ 0, 0.0, 'z'));
+ }
+
+ return result.get();
+}
+
+template <typename CompletionToken>
+typename asio::async_result<
+ typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int, double, char)>::type>::type
+deprecated_async_op_ex_3(asio::io_context& ctx,
+ bool ok, ASIO_MOVE_ARG(CompletionToken) token)
+{
+ typedef typename asio::handler_type<CompletionToken,
+ void(std::exception_ptr, int, double, char)>::type handler_type;
+
+ handler_type handler(ASIO_MOVE_CAST(CompletionToken)(token));
+
+ asio::async_result<handler_type> result(handler);
+
+ if (ok)
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::exception_ptr(), 42, 2.0, 'a'));
+ }
+ else
+ {
+ ctx.post(bindns::bind(ASIO_MOVE_CAST(handler_type)(handler),
+ std::make_exception_ptr(std::runtime_error("blah")),
+ 0, 0.0, 'z'));
+ }
+
+ return result.get();
+}
+
+} // namespace archetypes
+
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+#endif // ARCHETYPES_DEPRECATED_ASYNC_OPS_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_result.hpp b/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_result.hpp
new file mode 100644
index 00000000000..c395b37144a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/deprecated_async_result.hpp
@@ -0,0 +1,82 @@
+//
+// async_result.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_DEPRECATED_ASYNC_RESULT_HPP
+#define ARCHETYPES_DEPRECATED_ASYNC_RESULT_HPP
+
+#include <asio/async_result.hpp>
+
+#if !defined(ASIO_NO_DEPRECATED)
+
+#include <asio/handler_type.hpp>
+
+namespace archetypes {
+
+struct deprecated_lazy_handler
+{
+};
+
+struct deprecated_concrete_handler
+{
+ deprecated_concrete_handler(deprecated_lazy_handler)
+ {
+ }
+
+ template <typename Arg1>
+ void operator()(Arg1)
+ {
+ }
+
+ template <typename Arg1, typename Arg2>
+ void operator()(Arg1, Arg2)
+ {
+ }
+
+#if defined(ASIO_HAS_MOVE)
+ deprecated_concrete_handler(deprecated_concrete_handler&&) {}
+private:
+ deprecated_concrete_handler(const deprecated_concrete_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+} // namespace archetypes
+
+namespace asio {
+
+template <typename Signature>
+struct handler_type<archetypes::deprecated_lazy_handler, Signature>
+{
+ typedef archetypes::deprecated_concrete_handler type;
+};
+
+template <>
+class async_result<archetypes::deprecated_concrete_handler>
+{
+public:
+ // The return type of the initiating function.
+ typedef double type;
+
+ // Construct an async_result from a given handler.
+ explicit async_result(archetypes::deprecated_concrete_handler&)
+ {
+ }
+
+ // Obtain the value to be returned from the initiating function.
+ type get()
+ {
+ return 42;
+ }
+};
+
+} // namespace asio
+
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+#endif // ARCHETYPES_DEPRECATED_ASYNC_RESULT_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/gettable_socket_option.hpp b/3rdparty/asio/src/tests/unit/archetypes/gettable_socket_option.hpp
new file mode 100644
index 00000000000..24544b0497a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/gettable_socket_option.hpp
@@ -0,0 +1,54 @@
+//
+// gettable_socket_option.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP
+#define ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP
+
+#include <cstddef>
+
+namespace archetypes {
+
+template <typename PointerType>
+class gettable_socket_option
+{
+public:
+ template <typename Protocol>
+ int level(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ int name(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ PointerType* data(const Protocol&)
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ std::size_t size(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ void resize(const Protocol&, std::size_t)
+ {
+ }
+};
+
+} // namespace archetypes
+
+#endif // ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/io_control_command.hpp b/3rdparty/asio/src/tests/unit/archetypes/io_control_command.hpp
new file mode 100644
index 00000000000..011eb07d8bd
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/io_control_command.hpp
@@ -0,0 +1,32 @@
+//
+// io_control_command.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_IO_CONTROL_COMMAND_HPP
+#define ARCHETYPES_IO_CONTROL_COMMAND_HPP
+
+namespace archetypes {
+
+class io_control_command
+{
+public:
+ int name() const
+ {
+ return 0;
+ }
+
+ void* data()
+ {
+ return 0;
+ }
+};
+
+} // namespace archetypes
+
+#endif // ARCHETYPES_IO_CONTROL_COMMAND_HPP
diff --git a/3rdparty/asio/src/tests/unit/archetypes/settable_socket_option.hpp b/3rdparty/asio/src/tests/unit/archetypes/settable_socket_option.hpp
new file mode 100644
index 00000000000..99b4dac899e
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/archetypes/settable_socket_option.hpp
@@ -0,0 +1,49 @@
+//
+// settable_socket_option.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP
+#define ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP
+
+#include <cstddef>
+
+namespace archetypes {
+
+template <typename PointerType>
+class settable_socket_option
+{
+public:
+ template <typename Protocol>
+ int level(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ int name(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ const PointerType* data(const Protocol&) const
+ {
+ return 0;
+ }
+
+ template <typename Protocol>
+ std::size_t size(const Protocol&) const
+ {
+ return 0;
+ }
+};
+
+} // namespace archetypes
+
+#endif // ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP
diff --git a/3rdparty/asio/src/tests/unit/associated_allocator.cpp b/3rdparty/asio/src/tests/unit/associated_allocator.cpp
new file mode 100644
index 00000000000..7fe80ab3276
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/associated_allocator.cpp
@@ -0,0 +1,25 @@
+//
+// associated_allocator.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/associated_allocator.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "associated_allocator",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/associated_executor.cpp b/3rdparty/asio/src/tests/unit/associated_executor.cpp
new file mode 100644
index 00000000000..a91fbb6336b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/associated_executor.cpp
@@ -0,0 +1,25 @@
+//
+// associated_executor.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/associated_executor.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "associated_executor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/async_result.cpp b/3rdparty/asio/src/tests/unit/async_result.cpp
new file mode 100644
index 00000000000..479aeb56e7d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/async_result.cpp
@@ -0,0 +1,25 @@
+//
+// async_result.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/async_result.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "async_result",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_datagram_socket.cpp b/3rdparty/asio/src/tests/unit/basic_datagram_socket.cpp
new file mode 100644
index 00000000000..8b17b5e9503
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_datagram_socket.cpp
@@ -0,0 +1,25 @@
+//
+// basic_datagram_socket.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_datagram_socket.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_datagram_socket",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_deadline_timer.cpp b/3rdparty/asio/src/tests/unit/basic_deadline_timer.cpp
new file mode 100644
index 00000000000..65244031a59
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_deadline_timer.cpp
@@ -0,0 +1,25 @@
+//
+// basic_deadline_timer.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_deadline_timer.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_deadline_timer",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_raw_socket.cpp b/3rdparty/asio/src/tests/unit/basic_raw_socket.cpp
new file mode 100644
index 00000000000..0b983e378f5
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_raw_socket.cpp
@@ -0,0 +1,25 @@
+//
+// basic_raw_socket.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_raw_socket.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_raw_socket",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_seq_packet_socket.cpp b/3rdparty/asio/src/tests/unit/basic_seq_packet_socket.cpp
new file mode 100644
index 00000000000..c9f325d5908
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_seq_packet_socket.cpp
@@ -0,0 +1,25 @@
+//
+// basic_seq_packet_socket.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_seq_packet_socket.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_seq_packet_socket",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_serial_port.cpp b/3rdparty/asio/src/tests/unit/basic_serial_port.cpp
new file mode 100644
index 00000000000..a6c4e67d54a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_serial_port.cpp
@@ -0,0 +1,26 @@
+//
+// basic_serial_port.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_serial_port.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_serial_port",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_signal_set.cpp b/3rdparty/asio/src/tests/unit/basic_signal_set.cpp
new file mode 100644
index 00000000000..f3f87c5185a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_signal_set.cpp
@@ -0,0 +1,25 @@
+//
+// basic_signal_set.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_signal_set.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_signal_set",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_socket_acceptor.cpp b/3rdparty/asio/src/tests/unit/basic_socket_acceptor.cpp
new file mode 100644
index 00000000000..4e6629f2b69
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_socket_acceptor.cpp
@@ -0,0 +1,25 @@
+//
+// basic_socket_acceptor.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_socket_acceptor.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_socket_acceptor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_stream_socket.cpp b/3rdparty/asio/src/tests/unit/basic_stream_socket.cpp
new file mode 100644
index 00000000000..b04a4dc82bd
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_stream_socket.cpp
@@ -0,0 +1,25 @@
+//
+// basic_stream_socket.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_stream_socket.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_stream_socket",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_streambuf.cpp b/3rdparty/asio/src/tests/unit/basic_streambuf.cpp
new file mode 100644
index 00000000000..ff9166205c9
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_streambuf.cpp
@@ -0,0 +1,25 @@
+//
+// basic_streambuf.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_streambuf.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_streambuf",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/basic_waitable_timer.cpp b/3rdparty/asio/src/tests/unit/basic_waitable_timer.cpp
new file mode 100644
index 00000000000..6aa90cb2387
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/basic_waitable_timer.cpp
@@ -0,0 +1,25 @@
+//
+// basic_waitable_timer.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/basic_waitable_timer.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "basic_waitable_timer",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/bind_executor.cpp b/3rdparty/asio/src/tests/unit/bind_executor.cpp
new file mode 100644
index 00000000000..74f24638a62
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/bind_executor.cpp
@@ -0,0 +1,25 @@
+//
+// bind_executor.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/bind_executor.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "bind_executor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/buffer.cpp b/3rdparty/asio/src/tests/unit/buffer.cpp
new file mode 100644
index 00000000000..b28533059ca
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/buffer.cpp
@@ -0,0 +1,567 @@
+//
+// buffer.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/buffer.hpp"
+
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+//------------------------------------------------------------------------------
+
+// buffer_compile test
+// ~~~~~~~~~~~~~~~~~~~
+// The following test checks that all overloads of the buffer function compile
+// and link correctly. Runtime failures are ignored.
+
+namespace buffer_compile {
+
+using namespace asio;
+
+void test()
+{
+ try
+ {
+ char raw_data[1024];
+ const char const_raw_data[1024] = "";
+ void* void_ptr_data = raw_data;
+ const void* const_void_ptr_data = const_raw_data;
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ boost::array<char, 1024> array_data;
+ const boost::array<char, 1024>& const_array_data_1 = array_data;
+ boost::array<const char, 1024> const_array_data_2 = { { 0 } };
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+#if defined(ASIO_HAS_STD_ARRAY)
+ std::array<char, 1024> std_array_data;
+ const std::array<char, 1024>& const_std_array_data_1 = std_array_data;
+ std::array<const char, 1024> const_std_array_data_2 = { { 0 } };
+#endif // defined(ASIO_HAS_STD_ARRAY)
+ std::vector<char> vector_data(1024);
+ const std::vector<char>& const_vector_data = vector_data;
+ std::string string_data(1024, ' ');
+ const std::string const_string_data(1024, ' ');
+ std::vector<mutable_buffer> mutable_buffer_sequence;
+ std::vector<const_buffer> const_buffer_sequence;
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_data(string_data);
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_data(string_data);
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // mutable_buffer constructors.
+
+ mutable_buffer mb1;
+ mutable_buffer mb2(void_ptr_data, 1024);
+ mutable_buffer mb3(mb1);
+
+ // mutable_buffer functions.
+
+ void* ptr1 = mb1.data();
+ (void)ptr1;
+
+ std::size_t n1 = mb1.size();
+ (void)n1;
+
+ // mutable_buffer operators.
+
+ mb1 += 128;
+ mb1 = mb2 + 128;
+ mb1 = 128 + mb2;
+
+#if !defined(ASIO_NO_DEPRECATED)
+
+ // mutable_buffers_1 constructors.
+
+ mutable_buffers_1 mbc1(mb1);
+ mutable_buffers_1 mbc2(mbc1);
+
+ // mutable_buffers_1 functions.
+
+ mutable_buffers_1::const_iterator iter1 = mbc1.begin();
+ (void)iter1;
+ mutable_buffers_1::const_iterator iter2 = mbc1.end();
+ (void)iter2;
+
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // const_buffer constructors.
+
+ const_buffer cb1;
+ const_buffer cb2(const_void_ptr_data, 1024);
+ const_buffer cb3(cb1);
+ const_buffer cb4(mb1);
+
+ // const_buffer functions.
+
+ const void* ptr2 = cb1.data();
+ (void)ptr2;
+
+ std::size_t n2 = cb1.size();
+ (void)n2;
+
+ // const_buffer operators.
+
+ cb1 += 128;
+ cb1 = cb2 + 128;
+ cb1 = 128 + cb2;
+
+#if !defined(ASIO_NO_DEPRECATED)
+
+ // const_buffers_1 constructors.
+
+ const_buffers_1 cbc1(cb1);
+ const_buffers_1 cbc2(cbc1);
+
+ // const_buffers_1 functions.
+
+ const_buffers_1::const_iterator iter3 = cbc1.begin();
+ (void)iter3;
+ const_buffers_1::const_iterator iter4 = cbc1.end();
+ (void)iter4;
+
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // buffer_size function overloads.
+
+ std::size_t size1 = buffer_size(mb1);
+ (void)size1;
+ std::size_t size2 = buffer_size(cb1);
+ (void)size2;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size3 = buffer_size(mbc1);
+ (void)size3;
+ std::size_t size4 = buffer_size(cbc1);
+ (void)size4;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size5 = buffer_size(mutable_buffer_sequence);
+ (void)size5;
+ std::size_t size6 = buffer_size(const_buffer_sequence);
+ (void)size6;
+
+ // buffer_cast function overloads.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ void* ptr3 = buffer_cast<void*>(mb1);
+ (void)ptr3;
+ const void* ptr4 = buffer_cast<const void*>(cb1);
+ (void)ptr4;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // buffer function overloads.
+
+ mb1 = buffer(mb2);
+ mb1 = buffer(mb2, 128);
+ cb1 = buffer(cb2);
+ cb1 = buffer(cb2, 128);
+ mb1 = buffer(void_ptr_data, 1024);
+ cb1 = buffer(const_void_ptr_data, 1024);
+ mb1 = buffer(raw_data);
+ mb1 = buffer(raw_data, 1024);
+ cb1 = buffer(const_raw_data);
+ cb1 = buffer(const_raw_data, 1024);
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ mb1 = buffer(array_data);
+ mb1 = buffer(array_data, 1024);
+ cb1 = buffer(const_array_data_1);
+ cb1 = buffer(const_array_data_1, 1024);
+ cb1 = buffer(const_array_data_2);
+ cb1 = buffer(const_array_data_2, 1024);
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+#if defined(ASIO_HAS_STD_ARRAY)
+ mb1 = buffer(std_array_data);
+ mb1 = buffer(std_array_data, 1024);
+ cb1 = buffer(const_std_array_data_1);
+ cb1 = buffer(const_std_array_data_1, 1024);
+ cb1 = buffer(const_std_array_data_2);
+ cb1 = buffer(const_std_array_data_2, 1024);
+#endif // defined(ASIO_HAS_STD_ARRAY)
+ mb1 = buffer(vector_data);
+ mb1 = buffer(vector_data, 1024);
+ cb1 = buffer(const_vector_data);
+ cb1 = buffer(const_vector_data, 1024);
+ mb1 = buffer(string_data);
+ mb1 = buffer(string_data, 1024);
+ cb1 = buffer(const_string_data);
+ cb1 = buffer(const_string_data, 1024);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+ cb1 = buffer(string_view_data);
+ cb1 = buffer(string_view_data, 1024);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // buffer_copy function overloads.
+
+ std::size_t size7 = buffer_copy(mb1, cb2);
+ (void)size7;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size8 = buffer_copy(mb1, cbc2);
+ (void)size8;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size9 = buffer_copy(mb1, mb2);
+ (void)size9;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size10 = buffer_copy(mb1, mbc2);
+ (void)size10;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size11 = buffer_copy(mb1, const_buffer_sequence);
+ (void)size11;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size12 = buffer_copy(mbc1, cb2);
+ (void)size12;
+ std::size_t size13 = buffer_copy(mbc1, cbc2);
+ (void)size13;
+ std::size_t size14 = buffer_copy(mbc1, mb2);
+ (void)size14;
+ std::size_t size15 = buffer_copy(mbc1, mbc2);
+ (void)size15;
+ std::size_t size16 = buffer_copy(mbc1, const_buffer_sequence);
+ (void)size16;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size17 = buffer_copy(mutable_buffer_sequence, cb2);
+ (void)size17;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size18 = buffer_copy(mutable_buffer_sequence, cbc2);
+ (void)size18;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size19 = buffer_copy(mutable_buffer_sequence, mb2);
+ (void)size19;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size20 = buffer_copy(mutable_buffer_sequence, mbc2);
+ (void)size20;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size21 = buffer_copy(
+ mutable_buffer_sequence, const_buffer_sequence);
+ (void)size21;
+ std::size_t size22 = buffer_copy(mb1, cb2, 128);
+ (void)size22;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size23 = buffer_copy(mb1, cbc2, 128);
+ (void)size23;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size24 = buffer_copy(mb1, mb2, 128);
+ (void)size24;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size25 = buffer_copy(mb1, mbc2, 128);
+ (void)size25;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size26 = buffer_copy(mb1, const_buffer_sequence, 128);
+ (void)size26;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size27 = buffer_copy(mbc1, cb2, 128);
+ (void)size27;
+ std::size_t size28 = buffer_copy(mbc1, cbc2, 128);
+ (void)size28;
+ std::size_t size29 = buffer_copy(mbc1, mb2, 128);
+ (void)size29;
+ std::size_t size30 = buffer_copy(mbc1, mbc2, 128);
+ (void)size30;
+ std::size_t size31 = buffer_copy(mbc1, const_buffer_sequence, 128);
+ (void)size31;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size32 = buffer_copy(mutable_buffer_sequence, cb2, 128);
+ (void)size32;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size33 = buffer_copy(mutable_buffer_sequence, cbc2, 128);
+ (void)size33;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size34 = buffer_copy(mutable_buffer_sequence, mb2, 128);
+ (void)size34;
+#if !defined(ASIO_NO_DEPRECATED)
+ std::size_t size35 = buffer_copy(mutable_buffer_sequence, mbc2, 128);
+ (void)size35;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ std::size_t size36 = buffer_copy(
+ mutable_buffer_sequence, const_buffer_sequence, 128);
+ (void)size36;
+
+ // dynamic_buffer function overloads.
+
+ dynamic_string_buffer<char, std::string::traits_type,
+ std::string::allocator_type> db1 = dynamic_buffer(string_data);
+ (void)db1;
+ dynamic_string_buffer<char, std::string::traits_type,
+ std::string::allocator_type> db2 = dynamic_buffer(string_data, 1024);
+ (void)db2;
+ dynamic_vector_buffer<char, std::allocator<char> >
+ db3 = dynamic_buffer(vector_data);
+ (void)db3;
+ dynamic_vector_buffer<char, std::allocator<char> >
+ db4 = dynamic_buffer(vector_data, 1024);
+ (void)db4;
+
+ // dynamic_buffer member functions.
+
+ std::size_t size37 = db1.size();
+ (void)size37;
+ std::size_t size38 = db3.size();
+ (void)size38;
+
+ std::size_t size39 = db1.max_size();
+ (void)size39;
+ std::size_t size40 = db3.max_size();
+ (void)size40;
+
+ dynamic_string_buffer<char, std::string::traits_type,
+ std::string::allocator_type>::const_buffers_type
+ cb5 = db1.data();
+ (void)cb5;
+ dynamic_vector_buffer<char, std::allocator<char> >::const_buffers_type
+ cb6 = db3.data();
+ (void)cb6;
+
+ dynamic_string_buffer<char, std::string::traits_type,
+ std::string::allocator_type>::mutable_buffers_type mb5
+ = db1.prepare(1024);
+ (void)mb5;
+ dynamic_vector_buffer<char, std::allocator<char> >::mutable_buffers_type
+ mb6 = db3.prepare(1024);
+ (void)mb6;
+
+ db1.commit(1024);
+ db3.commit(1024);
+
+ db1.consume(1024);
+ db3.consume(1024);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace buffer_compile
+
+//------------------------------------------------------------------------------
+
+namespace buffer_copy_runtime {
+
+using namespace asio;
+using namespace std;
+
+void test()
+{
+ char dest_data[256];
+ char source_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mutable_buffer mb1 = asio::buffer(dest_data);
+ mutable_buffer mb2 = asio::buffer(source_data);
+ std::size_t n = buffer_copy(mb1, mb2);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ const_buffer cb1 = asio::buffer(source_data);
+ n = buffer_copy(mb1, cb1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+#if !defined(ASIO_NO_DEPRECATED)
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ mutable_buffers_1 mbc1 = asio::buffer(source_data);
+ n = buffer_copy(mb1, mbc1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ const_buffers_1 cbc1 = const_buffers_1(asio::buffer(source_data));
+ n = buffer_copy(mb1, cbc1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ mb1 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, mb1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ cb1 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, cb1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ mutable_buffers_1 mbc2 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, mbc2);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ cbc1 = const_buffers_1(asio::buffer(source_data));
+ n = buffer_copy(mbc1, cbc1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ std::vector<mutable_buffer> mv1;
+ mv1.push_back(asio::buffer(source_data, 5));
+ mv1.push_back(asio::buffer(source_data) + 5);
+ n = buffer_copy(mb1, mv1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ std::vector<const_buffer> cv1;
+ cv1.push_back(asio::buffer(source_data, 6));
+ cv1.push_back(asio::buffer(source_data) + 6);
+ n = buffer_copy(mb1, cv1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mv1.clear();
+ mv1.push_back(asio::buffer(dest_data, 7));
+ mv1.push_back(asio::buffer(dest_data) + 7);
+ cb1 = asio::buffer(source_data);
+ n = buffer_copy(mv1, cb1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mv1.clear();
+ mv1.push_back(asio::buffer(dest_data, 7));
+ mv1.push_back(asio::buffer(dest_data) + 7);
+ cv1.clear();
+ cv1.push_back(asio::buffer(source_data, 8));
+ cv1.push_back(asio::buffer(source_data) + 8);
+ n = buffer_copy(mv1, cv1);
+ ASIO_CHECK(n == sizeof(source_data));
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ mb2 = asio::buffer(source_data);
+ n = buffer_copy(mb1, mb2, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ cb1 = asio::buffer(source_data);
+ n = buffer_copy(mb1, cb1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+#if !defined(ASIO_NO_DEPRECATED)
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ mbc1 = asio::buffer(source_data);
+ n = buffer_copy(mb1, mbc1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ cbc1 = const_buffers_1(asio::buffer(source_data));
+ n = buffer_copy(mb1, cbc1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ mb1 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, mb1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ cb1 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, cb1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ mbc2 = asio::buffer(source_data);
+ n = buffer_copy(mbc1, mbc2, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mbc1 = asio::buffer(dest_data);
+ cbc1 = const_buffers_1(asio::buffer(source_data));
+ n = buffer_copy(mbc1, cbc1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ mv1.clear();
+ mv1.push_back(asio::buffer(source_data, 5));
+ mv1.push_back(asio::buffer(source_data) + 5);
+ n = buffer_copy(mb1, mv1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mb1 = asio::buffer(dest_data);
+ cv1.clear();
+ cv1.push_back(asio::buffer(source_data, 6));
+ cv1.push_back(asio::buffer(source_data) + 6);
+ n = buffer_copy(mb1, cv1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mv1.clear();
+ mv1.push_back(asio::buffer(dest_data, 7));
+ mv1.push_back(asio::buffer(dest_data) + 7);
+ cb1 = asio::buffer(source_data);
+ n = buffer_copy(mv1, cb1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+ memset(dest_data, 0, sizeof(dest_data));
+ mv1.clear();
+ mv1.push_back(asio::buffer(dest_data, 7));
+ mv1.push_back(asio::buffer(dest_data) + 7);
+ cv1.clear();
+ cv1.push_back(asio::buffer(source_data, 8));
+ cv1.push_back(asio::buffer(source_data) + 8);
+ n = buffer_copy(mv1, cv1, 10);
+ ASIO_CHECK(n == 10);
+ ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+}
+
+} // namespace buffer_copy_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "buffer",
+ ASIO_COMPILE_TEST_CASE(buffer_compile::test)
+ ASIO_TEST_CASE(buffer_copy_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/buffered_read_stream.cpp b/3rdparty/asio/src/tests/unit/buffered_read_stream.cpp
new file mode 100644
index 00000000000..28a0db1eb93
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/buffered_read_stream.cpp
@@ -0,0 +1,346 @@
+//
+// buffered_read_stream.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/buffered_read_stream.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/buffer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/system_error.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+typedef asio::buffered_read_stream<
+ asio::ip::tcp::socket> stream_type;
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void fill_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test_compile()
+{
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ using boost::array;
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+ using std::array;
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ array<asio::mutable_buffer, 2> mutable_buffers = {{
+ asio::buffer(mutable_char_buffer, 10),
+ asio::buffer(mutable_char_buffer + 10, 10) }};
+ array<asio::const_buffer, 2> const_buffers = {{
+ asio::buffer(const_char_buffer, 10),
+ asio::buffer(const_char_buffer + 10, 10) }};
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ stream_type stream1(ioc);
+ stream_type stream2(ioc, 1024);
+
+ stream_type::executor_type ex = stream1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = stream1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = stream1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
+ (void)lowest_layer;
+
+ stream1.write_some(buffer(mutable_char_buffer));
+ stream1.write_some(buffer(const_char_buffer));
+ stream1.write_some(mutable_buffers);
+ stream1.write_some(const_buffers);
+ stream1.write_some(null_buffers());
+ stream1.write_some(buffer(mutable_char_buffer), ec);
+ stream1.write_some(buffer(const_char_buffer), ec);
+ stream1.write_some(mutable_buffers, ec);
+ stream1.write_some(const_buffers, ec);
+ stream1.write_some(null_buffers(), ec);
+
+ stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
+ stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
+ stream1.async_write_some(mutable_buffers, &write_some_handler);
+ stream1.async_write_some(const_buffers, &write_some_handler);
+ stream1.async_write_some(null_buffers(), &write_some_handler);
+ int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i2;
+ int i3 = stream1.async_write_some(mutable_buffers, lazy);
+ (void)i3;
+ int i4 = stream1.async_write_some(const_buffers, lazy);
+ (void)i4;
+ int i5 = stream1.async_write_some(null_buffers(), lazy);
+ (void)i5;
+
+ stream1.fill();
+ stream1.fill(ec);
+
+ stream1.async_fill(&fill_handler);
+ int i6 = stream1.async_fill(lazy);
+ (void)i6;
+
+ stream1.read_some(buffer(mutable_char_buffer));
+ stream1.read_some(mutable_buffers);
+ stream1.read_some(null_buffers());
+ stream1.read_some(buffer(mutable_char_buffer), ec);
+ stream1.read_some(mutable_buffers, ec);
+ stream1.read_some(null_buffers(), ec);
+
+ stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
+ stream1.async_read_some(mutable_buffers, &read_some_handler);
+ stream1.async_read_some(null_buffers(), &read_some_handler);
+ int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i7;
+ int i8 = stream1.async_read_some(mutable_buffers, lazy);
+ (void)i8;
+ int i9 = stream1.async_read_some(null_buffers(), lazy);
+ (void)i9;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+void test_sync_operations()
+{
+ using namespace std; // For memcmp.
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.accept(server_socket.lowest_layer());
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += client_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += server_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += server_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += client_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ asio::error_code error;
+ bytes_read = client_socket.read_some(
+ asio::buffer(read_buf), error);
+
+ ASIO_CHECK(bytes_read == 0);
+ ASIO_CHECK(error == asio::error::eof);
+
+ client_socket.close(error);
+}
+
+void handle_accept(const asio::error_code& e)
+{
+ ASIO_CHECK(!e);
+}
+
+void handle_write(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_written)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_written += bytes_transferred;
+}
+
+void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_read)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_read += bytes_transferred;
+}
+
+void handle_read_eof(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ ASIO_CHECK(e == asio::error::eof);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test_async_operations()
+{
+ using namespace std; // For memcmp.
+
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
+ io_context.run();
+ io_context.restart();
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ client_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ server_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ server_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ client_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ client_socket.async_read_some(asio::buffer(read_buf), handle_read_eof);
+}
+
+ASIO_TEST_SUITE
+(
+ "buffered_read_stream",
+ ASIO_TEST_CASE(test_compile)
+ ASIO_TEST_CASE(test_sync_operations)
+ ASIO_TEST_CASE(test_async_operations)
+)
diff --git a/3rdparty/asio/src/tests/unit/buffered_stream.cpp b/3rdparty/asio/src/tests/unit/buffered_stream.cpp
new file mode 100644
index 00000000000..7e077d0ca71
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/buffered_stream.cpp
@@ -0,0 +1,372 @@
+//
+// buffered_stream.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/buffered_stream.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/buffer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/system_error.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+typedef asio::buffered_stream<
+ asio::ip::tcp::socket> stream_type;
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void flush_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void fill_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test_compile()
+{
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ using boost::array;
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+ using std::array;
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ array<asio::mutable_buffer, 2> mutable_buffers = {{
+ asio::buffer(mutable_char_buffer, 10),
+ asio::buffer(mutable_char_buffer + 10, 10) }};
+ array<asio::const_buffer, 2> const_buffers = {{
+ asio::buffer(const_char_buffer, 10),
+ asio::buffer(const_char_buffer + 10, 10) }};
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ stream_type stream1(ioc);
+ stream_type stream2(ioc, 1024, 1024);
+
+ stream_type::executor_type ex = stream1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = stream1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = stream1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
+ (void)lowest_layer;
+
+ stream1.write_some(buffer(mutable_char_buffer));
+ stream1.write_some(buffer(const_char_buffer));
+ stream1.write_some(mutable_buffers);
+ stream1.write_some(const_buffers);
+ stream1.write_some(null_buffers());
+ stream1.write_some(buffer(mutable_char_buffer), ec);
+ stream1.write_some(buffer(const_char_buffer), ec);
+ stream1.write_some(mutable_buffers, ec);
+ stream1.write_some(const_buffers, ec);
+ stream1.write_some(null_buffers(), ec);
+
+ stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
+ stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
+ stream1.async_write_some(mutable_buffers, &write_some_handler);
+ stream1.async_write_some(const_buffers, &write_some_handler);
+ stream1.async_write_some(null_buffers(), &write_some_handler);
+ int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i2;
+ int i3 = stream1.async_write_some(mutable_buffers, lazy);
+ (void)i3;
+ int i4 = stream1.async_write_some(const_buffers, lazy);
+ (void)i4;
+ int i5 = stream1.async_write_some(null_buffers(), lazy);
+ (void)i5;
+
+ stream1.flush();
+ stream1.flush(ec);
+
+ stream1.async_flush(&flush_handler);
+ int i6 = stream1.async_flush(lazy);
+ (void)i6;
+
+ stream1.fill();
+ stream1.fill(ec);
+
+ stream1.async_fill(&fill_handler);
+ int i7 = stream1.async_fill(lazy);
+ (void)i7;
+
+ stream1.read_some(buffer(mutable_char_buffer));
+ stream1.read_some(mutable_buffers);
+ stream1.read_some(null_buffers());
+ stream1.read_some(buffer(mutable_char_buffer), ec);
+ stream1.read_some(mutable_buffers, ec);
+ stream1.read_some(null_buffers(), ec);
+
+ stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
+ stream1.async_read_some(mutable_buffers, &read_some_handler);
+ stream1.async_read_some(null_buffers(), &read_some_handler);
+ int i8 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i8;
+ int i9 = stream1.async_read_some(mutable_buffers, lazy);
+ (void)i9;
+ int i10 = stream1.async_read_some(null_buffers(), lazy);
+ (void)i10;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+void test_sync_operations()
+{
+ using namespace std; // For memcmp.
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.accept(server_socket.lowest_layer());
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += client_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ client_socket.flush();
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += server_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += server_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ server_socket.flush();
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += client_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ asio::error_code error;
+ bytes_read = client_socket.read_some(
+ asio::buffer(read_buf), error);
+
+ ASIO_CHECK(bytes_read == 0);
+ ASIO_CHECK(error == asio::error::eof);
+
+ client_socket.close(error);
+}
+
+void handle_accept(const asio::error_code& e)
+{
+ ASIO_CHECK(!e);
+}
+
+void handle_write(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_written)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_written += bytes_transferred;
+}
+
+void handle_flush(const asio::error_code& e)
+{
+ ASIO_CHECK(!e);
+}
+
+void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_read)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_read += bytes_transferred;
+}
+
+void handle_read_eof(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ ASIO_CHECK(e == asio::error::eof);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test_async_operations()
+{
+ using namespace std; // For memcmp.
+
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
+ io_context.run();
+ io_context.restart();
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ client_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ client_socket.async_flush(
+ bindns::bind(handle_flush, _1));
+ io_context.run();
+ io_context.restart();
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ server_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ server_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ server_socket.async_flush(
+ bindns::bind(handle_flush, _1));
+ io_context.run();
+ io_context.restart();
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ client_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ client_socket.async_read_some(asio::buffer(read_buf), handle_read_eof);
+}
+
+ASIO_TEST_SUITE
+(
+ "buffered_stream",
+ ASIO_TEST_CASE(test_compile)
+ ASIO_TEST_CASE(test_sync_operations)
+ ASIO_TEST_CASE(test_async_operations)
+)
diff --git a/3rdparty/asio/src/tests/unit/buffered_write_stream.cpp b/3rdparty/asio/src/tests/unit/buffered_write_stream.cpp
new file mode 100644
index 00000000000..dd520505d33
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/buffered_write_stream.cpp
@@ -0,0 +1,361 @@
+//
+// buffered_write_stream.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/buffered_write_stream.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/buffer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/system_error.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+typedef asio::buffered_write_stream<
+ asio::ip::tcp::socket> stream_type;
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void flush_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test_compile()
+{
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ using boost::array;
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+ using std::array;
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ array<asio::mutable_buffer, 2> mutable_buffers = {{
+ asio::buffer(mutable_char_buffer, 10),
+ asio::buffer(mutable_char_buffer + 10, 10) }};
+ array<asio::const_buffer, 2> const_buffers = {{
+ asio::buffer(const_char_buffer, 10),
+ asio::buffer(const_char_buffer + 10, 10) }};
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ stream_type stream1(ioc);
+ stream_type stream2(ioc, 1024);
+
+ stream_type::executor_type ex = stream1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = stream1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = stream1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
+ (void)lowest_layer;
+
+ stream1.write_some(buffer(mutable_char_buffer));
+ stream1.write_some(buffer(const_char_buffer));
+ stream1.write_some(mutable_buffers);
+ stream1.write_some(const_buffers);
+ stream1.write_some(null_buffers());
+ stream1.write_some(buffer(mutable_char_buffer), ec);
+ stream1.write_some(buffer(const_char_buffer), ec);
+ stream1.write_some(mutable_buffers, ec);
+ stream1.write_some(const_buffers, ec);
+ stream1.write_some(null_buffers(), ec);
+
+ stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
+ stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
+ stream1.async_write_some(mutable_buffers, &write_some_handler);
+ stream1.async_write_some(const_buffers, &write_some_handler);
+ stream1.async_write_some(null_buffers(), &write_some_handler);
+ int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i2;
+ int i3 = stream1.async_write_some(mutable_buffers, lazy);
+ (void)i3;
+ int i4 = stream1.async_write_some(const_buffers, lazy);
+ (void)i4;
+ int i5 = stream1.async_write_some(null_buffers(), lazy);
+ (void)i5;
+
+ stream1.flush();
+ stream1.flush(ec);
+
+ stream1.async_flush(&flush_handler);
+ int i6 = stream1.async_flush(lazy);
+ (void)i6;
+
+ stream1.read_some(buffer(mutable_char_buffer));
+ stream1.read_some(mutable_buffers);
+ stream1.read_some(null_buffers());
+ stream1.read_some(buffer(mutable_char_buffer), ec);
+ stream1.read_some(mutable_buffers, ec);
+ stream1.read_some(null_buffers(), ec);
+
+ stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
+ stream1.async_read_some(mutable_buffers, &read_some_handler);
+ stream1.async_read_some(null_buffers(), &read_some_handler);
+ int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i7;
+ int i8 = stream1.async_read_some(mutable_buffers, lazy);
+ (void)i8;
+ int i9 = stream1.async_read_some(null_buffers(), lazy);
+ (void)i9;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+void test_sync_operations()
+{
+ using namespace std; // For memcmp.
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.accept(server_socket.lowest_layer());
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += client_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ client_socket.flush();
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += server_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ bytes_written += server_socket.write_some(
+ asio::buffer(write_buf + bytes_written));
+ server_socket.flush();
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ bytes_read += client_socket.read_some(
+ asio::buffer(read_buf + bytes_read));
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ asio::error_code error;
+ bytes_read = client_socket.read_some(
+ asio::buffer(read_buf), error);
+
+ ASIO_CHECK(bytes_read == 0);
+ ASIO_CHECK(error == asio::error::eof);
+
+ client_socket.close(error);
+}
+
+void handle_accept(const asio::error_code& e)
+{
+ ASIO_CHECK(!e);
+}
+
+void handle_write(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_written)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_written += bytes_transferred;
+}
+
+void handle_flush(const asio::error_code& e)
+{
+ ASIO_CHECK(!e);
+}
+
+void handle_read(const asio::error_code& e,
+ std::size_t bytes_transferred,
+ std::size_t* total_bytes_read)
+{
+ ASIO_CHECK(!e);
+ if (e)
+ throw asio::system_error(e); // Terminate test.
+ *total_bytes_read += bytes_transferred;
+}
+
+void handle_read_eof(const asio::error_code& e,
+ std::size_t bytes_transferred)
+{
+ ASIO_CHECK(e == asio::error::eof);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test_async_operations()
+{
+ using namespace std; // For memcmp.
+
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context io_context;
+
+ asio::ip::tcp::acceptor acceptor(io_context,
+ asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0));
+ asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(asio::ip::address_v4::loopback());
+
+ stream_type client_socket(io_context);
+ client_socket.lowest_layer().connect(server_endpoint);
+
+ stream_type server_socket(io_context);
+ acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
+ io_context.run();
+ io_context.restart();
+
+ const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ const asio::const_buffer write_buf = asio::buffer(write_data);
+
+ std::size_t bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ client_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ client_socket.async_flush(
+ bindns::bind(handle_flush, _1));
+ io_context.run();
+ io_context.restart();
+ }
+
+ char read_data[sizeof(write_data)];
+ const asio::mutable_buffer read_buf = asio::buffer(read_data);
+
+ std::size_t bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ server_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ bytes_written = 0;
+ while (bytes_written < sizeof(write_data))
+ {
+ server_socket.async_write_some(
+ asio::buffer(write_buf + bytes_written),
+ bindns::bind(handle_write, _1, _2, &bytes_written));
+ io_context.run();
+ io_context.restart();
+ server_socket.async_flush(
+ bindns::bind(handle_flush, _1));
+ io_context.run();
+ io_context.restart();
+ }
+
+ bytes_read = 0;
+ while (bytes_read < sizeof(read_data))
+ {
+ client_socket.async_read_some(
+ asio::buffer(read_buf + bytes_read),
+ bindns::bind(handle_read, _1, _2, &bytes_read));
+ io_context.run();
+ io_context.restart();
+ }
+
+ ASIO_CHECK(bytes_written == sizeof(write_data));
+ ASIO_CHECK(bytes_read == sizeof(read_data));
+ ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
+
+ server_socket.close();
+ client_socket.async_read_some(asio::buffer(read_buf), handle_read_eof);
+}
+
+ASIO_TEST_SUITE
+(
+ "buffered_write_stream",
+ ASIO_TEST_CASE(test_compile)
+ ASIO_TEST_CASE(test_sync_operations)
+ ASIO_TEST_CASE(test_async_operations)
+)
diff --git a/3rdparty/asio/src/tests/unit/buffers_iterator.cpp b/3rdparty/asio/src/tests/unit/buffers_iterator.cpp
new file mode 100644
index 00000000000..bd8c27522b2
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/buffers_iterator.cpp
@@ -0,0 +1,292 @@
+//
+// buffers_iterator.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/buffers_iterator.hpp"
+
+#include "asio/buffer.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+//------------------------------------------------------------------------------
+
+// buffers_iterator_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all operations on the buffers_iterator compile
+// and link correctly. Runtime failures are ignored.
+
+namespace buffers_iterator_compile {
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+using boost::array;
+#elif defined(ASIO_HAS_STD_ARRAY)
+using std::array;
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+using std::vector;
+using namespace asio;
+
+void test()
+{
+ try
+ {
+ char data1[16], data2[16];
+ const char cdata1[16] = "", cdata2[16] = "";
+ mutable_buffer mb1 = buffer(data1);
+ array<mutable_buffer, 2> mb2 = {{ buffer(data1), buffer(data2) }};
+ std::vector<mutable_buffer> mb3;
+ mb3.push_back(buffer(data1));
+ const_buffer cb1 = buffer(cdata1);
+ array<const_buffer, 2> cb2 = {{ buffer(cdata1), buffer(cdata2) }};
+ vector<const_buffer> cb3;
+ cb3.push_back(buffer(cdata1));
+
+
+ // buffers_iterator constructors.
+
+ buffers_iterator<mutable_buffer, char> bi1;
+ buffers_iterator<mutable_buffer, const char> bi2;
+ buffers_iterator<array<mutable_buffer, 2>, char> bi3;
+ buffers_iterator<array<mutable_buffer, 2>, const char> bi4;
+ buffers_iterator<vector<mutable_buffer>, char> bi5;
+ buffers_iterator<vector<mutable_buffer>, const char> bi6;
+ buffers_iterator<const_buffer, char> bi7;
+ buffers_iterator<const_buffer, const char> bi8;
+ buffers_iterator<array<const_buffer, 2>, char> bi9;
+ buffers_iterator<array<const_buffer, 2>, const char> bi10;
+ buffers_iterator<vector<const_buffer>, char> bi11;
+ buffers_iterator<vector<const_buffer>, const char> bi12;
+
+ buffers_iterator<mutable_buffer, char> bi13(
+ buffers_iterator<mutable_buffer, char>::begin(mb1));
+ buffers_iterator<mutable_buffer, const char> bi14(
+ buffers_iterator<mutable_buffer, const char>::begin(mb1));
+ buffers_iterator<array<mutable_buffer, 2>, char> bi15(
+ buffers_iterator<array<mutable_buffer, 2>, char>::begin(mb2));
+ buffers_iterator<array<mutable_buffer, 2>, const char> bi16(
+ buffers_iterator<array<mutable_buffer, 2>, const char>::begin(mb2));
+ buffers_iterator<vector<mutable_buffer>, char> bi17(
+ buffers_iterator<vector<mutable_buffer>, char>::begin(mb3));
+ buffers_iterator<vector<mutable_buffer>, const char> bi18(
+ buffers_iterator<vector<mutable_buffer>, const char>::begin(mb3));
+ buffers_iterator<const_buffer, char> bi19(
+ buffers_iterator<const_buffer, char>::begin(cb1));
+ buffers_iterator<const_buffer, const char> bi20(
+ buffers_iterator<const_buffer, const char>::begin(cb1));
+ buffers_iterator<array<const_buffer, 2>, char> bi21(
+ buffers_iterator<array<const_buffer, 2>, char>::begin(cb2));
+ buffers_iterator<array<const_buffer, 2>, const char> bi22(
+ buffers_iterator<array<const_buffer, 2>, const char>::begin(cb2));
+ buffers_iterator<vector<const_buffer>, char> bi23(
+ buffers_iterator<vector<const_buffer>, char>::begin(cb3));
+ buffers_iterator<vector<const_buffer>, const char> bi24(
+ buffers_iterator<vector<const_buffer>, const char>::begin(cb3));
+
+ // buffers_iterator member functions.
+
+ bi1 = buffers_iterator<mutable_buffer, char>::begin(mb1);
+ bi2 = buffers_iterator<mutable_buffer, const char>::begin(mb1);
+ bi3 = buffers_iterator<array<mutable_buffer, 2>, char>::begin(mb2);
+ bi4 = buffers_iterator<array<mutable_buffer, 2>, const char>::begin(mb2);
+ bi5 = buffers_iterator<vector<mutable_buffer>, char>::begin(mb3);
+ bi6 = buffers_iterator<vector<mutable_buffer>, const char>::begin(mb3);
+ bi7 = buffers_iterator<const_buffer, char>::begin(cb1);
+ bi8 = buffers_iterator<const_buffer, const char>::begin(cb1);
+ bi9 = buffers_iterator<array<const_buffer, 2>, char>::begin(cb2);
+ bi10 = buffers_iterator<array<const_buffer, 2>, const char>::begin(cb2);
+ bi11 = buffers_iterator<vector<const_buffer>, char>::begin(cb3);
+ bi12 = buffers_iterator<vector<const_buffer>, const char>::begin(cb3);
+
+ bi1 = buffers_iterator<mutable_buffer, char>::end(mb1);
+ bi2 = buffers_iterator<mutable_buffer, const char>::end(mb1);
+ bi3 = buffers_iterator<array<mutable_buffer, 2>, char>::end(mb2);
+ bi4 = buffers_iterator<array<mutable_buffer, 2>, const char>::end(mb2);
+ bi5 = buffers_iterator<vector<mutable_buffer>, char>::end(mb3);
+ bi6 = buffers_iterator<vector<mutable_buffer>, const char>::end(mb3);
+ bi7 = buffers_iterator<const_buffer, char>::end(cb1);
+ bi8 = buffers_iterator<const_buffer, const char>::end(cb1);
+ bi9 = buffers_iterator<array<const_buffer, 2>, char>::end(cb2);
+ bi10 = buffers_iterator<array<const_buffer, 2>, const char>::end(cb2);
+ bi11 = buffers_iterator<vector<const_buffer>, char>::end(cb3);
+ bi12 = buffers_iterator<vector<const_buffer>, const char>::end(cb3);
+
+ // buffers_iterator related functions.
+
+ bi1 = buffers_begin(mb1);
+ bi3 = buffers_begin(mb2);
+ bi5 = buffers_begin(mb3);
+ bi7 = buffers_begin(cb1);
+ bi9 = buffers_begin(cb2);
+ bi11 = buffers_begin(cb3);
+
+ bi1 = buffers_end(mb1);
+ bi3 = buffers_end(mb2);
+ bi5 = buffers_end(mb3);
+ bi7 = buffers_end(cb1);
+ bi9 = buffers_end(cb2);
+ bi11 = buffers_end(cb3);
+
+ // RandomAccessIterator operations.
+
+ --bi1;
+ --bi2;
+ --bi3;
+ --bi4;
+ --bi5;
+ --bi6;
+ --bi7;
+ --bi8;
+ --bi9;
+ --bi10;
+ --bi11;
+ --bi12;
+
+ ++bi1;
+ ++bi2;
+ ++bi3;
+ ++bi4;
+ ++bi5;
+ ++bi6;
+ ++bi7;
+ ++bi8;
+ ++bi9;
+ ++bi10;
+ ++bi11;
+ ++bi12;
+
+ bi1--;
+ bi2--;
+ bi3--;
+ bi4--;
+ bi5--;
+ bi6--;
+ bi7--;
+ bi8--;
+ bi9--;
+ bi10--;
+ bi11--;
+ bi12--;
+
+ bi1++;
+ bi2++;
+ bi3++;
+ bi4++;
+ bi5++;
+ bi6++;
+ bi7++;
+ bi8++;
+ bi9++;
+ bi10++;
+ bi11++;
+ bi12++;
+
+ bi1 -= 1;
+ bi2 -= 1;
+ bi3 -= 1;
+ bi4 -= 1;
+ bi5 -= 1;
+ bi6 -= 1;
+ bi7 -= 1;
+ bi8 -= 1;
+ bi9 -= 1;
+ bi10 -= 1;
+ bi11 -= 1;
+ bi12 -= 1;
+
+ bi1 += 1;
+ bi2 += 1;
+ bi3 += 1;
+ bi4 += 1;
+ bi5 += 1;
+ bi6 += 1;
+ bi7 += 1;
+ bi8 += 1;
+ bi9 += 1;
+ bi10 += 1;
+ bi11 += 1;
+ bi12 += 1;
+
+ bi1 = bi1 - 1;
+ bi2 = bi2 - 1;
+ bi3 = bi3 - 1;
+ bi4 = bi4 - 1;
+ bi5 = bi5 - 1;
+ bi6 = bi6 - 1;
+ bi7 = bi7 - 1;
+ bi8 = bi8 - 1;
+ bi9 = bi9 - 1;
+ bi10 = bi10 - 1;
+ bi11 = bi11 - 1;
+ bi12 = bi12 - 1;
+
+ bi1 = bi1 + 1;
+ bi2 = bi2 + 1;
+ bi3 = bi3 + 1;
+ bi4 = bi4 + 1;
+ bi5 = bi5 + 1;
+ bi6 = bi6 + 1;
+ bi7 = bi7 + 1;
+ bi8 = bi8 + 1;
+ bi9 = bi9 + 1;
+ bi10 = bi10 + 1;
+ bi11 = bi11 + 1;
+ bi12 = bi12 + 1;
+
+ bi1 = (-1) + bi1;
+ bi2 = (-1) + bi2;
+ bi3 = (-1) + bi3;
+ bi4 = (-1) + bi4;
+ bi5 = (-1) + bi5;
+ bi6 = (-1) + bi6;
+ bi7 = (-1) + bi7;
+ bi8 = (-1) + bi8;
+ bi9 = (-1) + bi9;
+ bi10 = (-1) + bi10;
+ bi11 = (-1) + bi11;
+ bi12 = (-1) + bi12;
+
+ (void)static_cast<std::ptrdiff_t>(bi13 - bi1);
+ (void)static_cast<std::ptrdiff_t>(bi14 - bi2);
+ (void)static_cast<std::ptrdiff_t>(bi15 - bi3);
+ (void)static_cast<std::ptrdiff_t>(bi16 - bi4);
+ (void)static_cast<std::ptrdiff_t>(bi17 - bi5);
+ (void)static_cast<std::ptrdiff_t>(bi18 - bi6);
+ (void)static_cast<std::ptrdiff_t>(bi19 - bi7);
+ (void)static_cast<std::ptrdiff_t>(bi20 - bi8);
+ (void)static_cast<std::ptrdiff_t>(bi21 - bi9);
+ (void)static_cast<std::ptrdiff_t>(bi22 - bi10);
+ (void)static_cast<std::ptrdiff_t>(bi23 - bi11);
+ (void)static_cast<std::ptrdiff_t>(bi24 - bi12);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace buffers_iterator_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "buffers_iterator",
+ ASIO_TEST_CASE(buffers_iterator_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/completion_condition.cpp b/3rdparty/asio/src/tests/unit/completion_condition.cpp
new file mode 100644
index 00000000000..43e64544728
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/completion_condition.cpp
@@ -0,0 +1,25 @@
+//
+// completion_condition.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/completion_condition.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "completion_condition",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/connect.cpp b/3rdparty/asio/src/tests/unit/connect.cpp
new file mode 100644
index 00000000000..3b0a43248f3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/connect.cpp
@@ -0,0 +1,25 @@
+//
+// connect.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/connect.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "connect",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/coroutine.cpp b/3rdparty/asio/src/tests/unit/coroutine.cpp
new file mode 100644
index 00000000000..162cacdbb6d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/coroutine.cpp
@@ -0,0 +1,112 @@
+//
+// coroutine.cpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/coroutine.hpp"
+
+#include "unit_test.hpp"
+
+// Must come after all other headers.
+#include "asio/yield.hpp"
+
+//------------------------------------------------------------------------------
+
+// Coroutine completes via yield break.
+
+void yield_break_coro(asio::coroutine& coro)
+{
+ reenter (coro)
+ {
+ yield return;
+ yield break;
+ }
+}
+
+void yield_break_test()
+{
+ asio::coroutine coro;
+ ASIO_CHECK(!coro.is_complete());
+ yield_break_coro(coro);
+ ASIO_CHECK(!coro.is_complete());
+ yield_break_coro(coro);
+ ASIO_CHECK(coro.is_complete());
+}
+
+//------------------------------------------------------------------------------
+
+// Coroutine completes via return.
+
+void return_coro(asio::coroutine& coro)
+{
+ reenter (coro)
+ {
+ return;
+ }
+}
+
+void return_test()
+{
+ asio::coroutine coro;
+ return_coro(coro);
+ ASIO_CHECK(coro.is_complete());
+}
+
+//------------------------------------------------------------------------------
+
+// Coroutine completes via exception.
+
+void exception_coro(asio::coroutine& coro)
+{
+ reenter (coro)
+ {
+ throw 1;
+ }
+}
+
+void exception_test()
+{
+ asio::coroutine coro;
+ try { exception_coro(coro); } catch (int) {}
+ ASIO_CHECK(coro.is_complete());
+}
+
+//------------------------------------------------------------------------------
+
+// Coroutine completes by falling off the end.
+
+void fall_off_end_coro(asio::coroutine& coro)
+{
+ reenter (coro)
+ {
+ }
+}
+
+void fall_off_end_test()
+{
+ asio::coroutine coro;
+ fall_off_end_coro(coro);
+ ASIO_CHECK(coro.is_complete());
+}
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "coroutine",
+ ASIO_TEST_CASE(yield_break_test)
+ ASIO_TEST_CASE(return_test)
+ ASIO_TEST_CASE(exception_test)
+ ASIO_TEST_CASE(fall_off_end_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/datagram_socket_service.cpp b/3rdparty/asio/src/tests/unit/datagram_socket_service.cpp
new file mode 100644
index 00000000000..5c4fe1374a6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/datagram_socket_service.cpp
@@ -0,0 +1,25 @@
+//
+// datagram_socket_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/datagram_socket_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "datagram_socket_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/deadline_timer.cpp b/3rdparty/asio/src/tests/unit/deadline_timer.cpp
new file mode 100644
index 00000000000..9c48b62c69a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/deadline_timer.cpp
@@ -0,0 +1,392 @@
+//
+// deadline_timer.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/deadline_timer.hpp"
+
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+
+#include <boost/bind.hpp>
+#include "archetypes/async_result.hpp"
+#include "asio/executor_work_guard.hpp"
+#include "asio/io_context.hpp"
+#include "asio/placeholders.hpp"
+#include "asio/thread.hpp"
+
+using namespace boost::posix_time;
+
+void increment(int* count)
+{
+ ++(*count);
+}
+
+void decrement_to_zero(asio::deadline_timer* t, int* count)
+{
+ if (*count > 0)
+ {
+ --(*count);
+
+ int before_value = *count;
+
+ t->expires_at(t->expires_at() + seconds(1));
+ t->async_wait(boost::bind(decrement_to_zero, t, count));
+
+ // Completion cannot nest, so count value should remain unchanged.
+ ASIO_CHECK(*count == before_value);
+ }
+}
+
+void increment_if_not_cancelled(int* count,
+ const asio::error_code& ec)
+{
+ if (!ec)
+ ++(*count);
+}
+
+void cancel_timer(asio::deadline_timer* t)
+{
+ std::size_t num_cancelled = t->cancel();
+ ASIO_CHECK(num_cancelled == 1);
+}
+
+void cancel_one_timer(asio::deadline_timer* t)
+{
+ std::size_t num_cancelled = t->cancel_one();
+ ASIO_CHECK(num_cancelled == 1);
+}
+
+ptime now()
+{
+#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ return microsec_clock::universal_time();
+#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ return second_clock::universal_time();
+#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+}
+
+void deadline_timer_test()
+{
+ asio::io_context ioc;
+ int count = 0;
+
+ ptime start = now();
+
+ asio::deadline_timer t1(ioc, seconds(1));
+ t1.wait();
+
+ // The timer must block until after its expiry time.
+ ptime end = now();
+ ptime expected_end = start + seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ asio::deadline_timer t2(ioc, seconds(1) + microseconds(500000));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end = start + seconds(1) + microseconds(500000);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ t2.expires_at(t2.expires_at() + seconds(1));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end += seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ t2.expires_from_now(seconds(1) + microseconds(200000));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end = start + seconds(1) + microseconds(200000);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ asio::deadline_timer t3(ioc, seconds(5));
+ t3.async_wait(boost::bind(increment, &count));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all operations have finished, and
+ // this should not be until after the timer's expiry time.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 3;
+ start = now();
+
+ asio::deadline_timer t4(ioc, seconds(1));
+ t4.async_wait(boost::bind(decrement_to_zero, &t4, &count));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 3);
+
+ ioc.restart();
+ ioc.run();
+
+ // The run() call will not return until all operations have finished, and
+ // this should not be until after the timer's final expiry time.
+ ASIO_CHECK(count == 0);
+ end = now();
+ expected_end = start + seconds(3);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 0;
+ start = now();
+
+ asio::deadline_timer t5(ioc, seconds(10));
+ t5.async_wait(boost::bind(increment_if_not_cancelled, &count,
+ asio::placeholders::error));
+ asio::deadline_timer t6(ioc, seconds(1));
+ t6.async_wait(boost::bind(cancel_timer, &t5));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.restart();
+ ioc.run();
+
+ // The timer should have been cancelled, so count should not have changed.
+ // The total run time should not have been much more than 1 second (and
+ // certainly far less than 10 seconds).
+ ASIO_CHECK(count == 0);
+ end = now();
+ expected_end = start + seconds(2);
+ ASIO_CHECK(end < expected_end);
+
+ // Wait on the timer again without cancelling it. This time the asynchronous
+ // wait should run to completion and increment the counter.
+ t5.async_wait(boost::bind(increment_if_not_cancelled, &count,
+ asio::placeholders::error));
+
+ ioc.restart();
+ ioc.run();
+
+ // The timer should not have been cancelled, so count should have changed.
+ // The total time since the timer was created should be more than 10 seconds.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(10);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 0;
+ start = now();
+
+ // Start two waits on a timer, one of which will be cancelled. The one
+ // which is not cancelled should still run to completion and increment the
+ // counter.
+ asio::deadline_timer t7(ioc, seconds(3));
+ t7.async_wait(boost::bind(increment_if_not_cancelled, &count,
+ asio::placeholders::error));
+ t7.async_wait(boost::bind(increment_if_not_cancelled, &count,
+ asio::placeholders::error));
+ asio::deadline_timer t8(ioc, seconds(1));
+ t8.async_wait(boost::bind(cancel_one_timer, &t7));
+
+ ioc.restart();
+ ioc.run();
+
+ // One of the waits should not have been cancelled, so count should have
+ // changed. The total time since the timer was created should be more than 3
+ // seconds.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(3);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+}
+
+void timer_handler(const asio::error_code&)
+{
+}
+
+void deadline_timer_cancel_test()
+{
+ static asio::io_context io_context;
+ struct timer
+ {
+ asio::deadline_timer t;
+ timer() : t(io_context) { t.expires_at(boost::posix_time::pos_infin); }
+ } timers[50];
+
+ timers[2].t.async_wait(&timer_handler);
+ timers[41].t.async_wait(&timer_handler);
+ for (int i = 10; i < 20; ++i)
+ timers[i].t.async_wait(&timer_handler);
+
+ ASIO_CHECK(timers[2].t.cancel() == 1);
+ ASIO_CHECK(timers[41].t.cancel() == 1);
+ for (int i = 10; i < 20; ++i)
+ ASIO_CHECK(timers[i].t.cancel() == 1);
+}
+
+struct custom_allocation_timer_handler
+{
+ custom_allocation_timer_handler(int* count) : count_(count) {}
+ void operator()(const asio::error_code&) {}
+ int* count_;
+};
+
+void* asio_handler_allocate(std::size_t size,
+ custom_allocation_timer_handler* handler)
+{
+ ++(*handler->count_);
+ return ::operator new(size);
+}
+
+void asio_handler_deallocate(void* pointer, std::size_t,
+ custom_allocation_timer_handler* handler)
+{
+ --(*handler->count_);
+ ::operator delete(pointer);
+}
+
+void deadline_timer_custom_allocation_test()
+{
+ static asio::io_context io_context;
+ struct timer
+ {
+ asio::deadline_timer t;
+ timer() : t(io_context) {}
+ } timers[100];
+
+ int allocation_count = 0;
+
+ for (int i = 0; i < 50; ++i)
+ {
+ timers[i].t.expires_at(boost::posix_time::pos_infin);
+ timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
+ }
+
+ for (int i = 50; i < 100; ++i)
+ {
+ timers[i].t.expires_at(boost::posix_time::neg_infin);
+ timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
+ }
+
+ for (int i = 0; i < 50; ++i)
+ timers[i].t.cancel();
+
+ io_context.run();
+
+ ASIO_CHECK(allocation_count == 0);
+}
+
+void io_context_run(asio::io_context* ioc)
+{
+ ioc->run();
+}
+
+void deadline_timer_thread_test()
+{
+ asio::io_context ioc;
+ asio::executor_work_guard<asio::io_context::executor_type> work
+ = asio::make_work_guard(ioc);
+ asio::deadline_timer t1(ioc);
+ asio::deadline_timer t2(ioc);
+ int count = 0;
+
+ asio::thread th(boost::bind(io_context_run, &ioc));
+
+ t2.expires_from_now(boost::posix_time::seconds(2));
+ t2.wait();
+
+ t1.expires_from_now(boost::posix_time::seconds(2));
+ t1.async_wait(boost::bind(increment, &count));
+
+ t2.expires_from_now(boost::posix_time::seconds(4));
+ t2.wait();
+
+ ioc.stop();
+ th.join();
+
+ ASIO_CHECK(count == 1);
+}
+
+void deadline_timer_async_result_test()
+{
+ asio::io_context ioc;
+ asio::deadline_timer t1(ioc);
+
+ t1.expires_from_now(boost::posix_time::seconds(1));
+ int i = t1.async_wait(archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+
+ ioc.run();
+}
+
+#if defined(ASIO_HAS_MOVE)
+asio::deadline_timer make_timer(asio::io_context& ioc, int* count)
+{
+ asio::deadline_timer t(ioc);
+ t.expires_from_now(boost::posix_time::seconds(1));
+ t.async_wait(boost::bind(increment, count));
+ return t;
+}
+#endif // defined(ASIO_HAS_MOVE)
+
+void deadline_timer_move_test()
+{
+#if defined(ASIO_HAS_MOVE)
+ asio::io_context io_context1;
+ asio::io_context io_context2;
+ int count = 0;
+
+ asio::deadline_timer t1 = make_timer(io_context1, &count);
+ asio::deadline_timer t2 = make_timer(io_context2, &count);
+ asio::deadline_timer t3 = std::move(t1);
+
+ t2 = std::move(t1);
+
+ io_context2.run();
+
+ ASIO_CHECK(count == 1);
+
+ io_context1.run();
+
+ ASIO_CHECK(count == 2);
+#endif // defined(ASIO_HAS_MOVE)
+}
+
+ASIO_TEST_SUITE
+(
+ "deadline_timer",
+ ASIO_TEST_CASE(deadline_timer_test)
+ ASIO_TEST_CASE(deadline_timer_cancel_test)
+ ASIO_TEST_CASE(deadline_timer_custom_allocation_test)
+ ASIO_TEST_CASE(deadline_timer_thread_test)
+ ASIO_TEST_CASE(deadline_timer_async_result_test)
+ ASIO_TEST_CASE(deadline_timer_move_test)
+)
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+ASIO_TEST_SUITE
+(
+ "deadline_timer",
+ ASIO_TEST_CASE(null_test)
+)
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
diff --git a/3rdparty/asio/src/tests/unit/deadline_timer_service.cpp b/3rdparty/asio/src/tests/unit/deadline_timer_service.cpp
new file mode 100644
index 00000000000..87c7aa6ad27
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/deadline_timer_service.cpp
@@ -0,0 +1,25 @@
+//
+// deadline_timer_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/deadline_timer_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "deadline_timer_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/defer.cpp b/3rdparty/asio/src/tests/unit/defer.cpp
new file mode 100644
index 00000000000..90163f636a5
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/defer.cpp
@@ -0,0 +1,25 @@
+//
+// defer.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/defer.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "defer",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/dispatch.cpp b/3rdparty/asio/src/tests/unit/dispatch.cpp
new file mode 100644
index 00000000000..64c20354bb9
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/dispatch.cpp
@@ -0,0 +1,25 @@
+//
+// dispatch.cpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/dispatch.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "dispatch",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/error.cpp b/3rdparty/asio/src/tests/unit/error.cpp
new file mode 100644
index 00000000000..d4c9b32106b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/error.cpp
@@ -0,0 +1,89 @@
+//
+// error.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/error.hpp"
+
+#include <sstream>
+#include "unit_test.hpp"
+
+void test_error_code(const asio::error_code& code)
+{
+ asio::error_code error(code);
+ ASIO_CHECK(code == error);
+
+ ASIO_CHECK(!code || error);
+ ASIO_CHECK(!code || !!error);
+
+ asio::error_code error2(error);
+ ASIO_CHECK(error == error2);
+ ASIO_CHECK(!(error != error2));
+
+ asio::error_code error3;
+ error3 = error;
+ ASIO_CHECK(error == error3);
+ ASIO_CHECK(!(error != error3));
+
+ std::ostringstream os;
+ os << error;
+ ASIO_CHECK(!os.str().empty());
+}
+
+void error_test()
+{
+ test_error_code(asio::error::access_denied);
+ test_error_code(asio::error::address_family_not_supported);
+ test_error_code(asio::error::address_in_use);
+ test_error_code(asio::error::already_connected);
+ test_error_code(asio::error::already_started);
+ test_error_code(asio::error::connection_aborted);
+ test_error_code(asio::error::connection_refused);
+ test_error_code(asio::error::connection_reset);
+ test_error_code(asio::error::bad_descriptor);
+ test_error_code(asio::error::eof);
+ test_error_code(asio::error::fault);
+ test_error_code(asio::error::host_not_found);
+ test_error_code(asio::error::host_not_found_try_again);
+ test_error_code(asio::error::host_unreachable);
+ test_error_code(asio::error::in_progress);
+ test_error_code(asio::error::interrupted);
+ test_error_code(asio::error::invalid_argument);
+ test_error_code(asio::error::message_size);
+ test_error_code(asio::error::network_down);
+ test_error_code(asio::error::network_reset);
+ test_error_code(asio::error::network_unreachable);
+ test_error_code(asio::error::no_descriptors);
+ test_error_code(asio::error::no_buffer_space);
+ test_error_code(asio::error::no_data);
+ test_error_code(asio::error::no_memory);
+ test_error_code(asio::error::no_permission);
+ test_error_code(asio::error::no_protocol_option);
+ test_error_code(asio::error::no_recovery);
+ test_error_code(asio::error::not_connected);
+ test_error_code(asio::error::not_socket);
+ test_error_code(asio::error::operation_aborted);
+ test_error_code(asio::error::operation_not_supported);
+ test_error_code(asio::error::service_not_found);
+ test_error_code(asio::error::shut_down);
+ test_error_code(asio::error::timed_out);
+ test_error_code(asio::error::try_again);
+ test_error_code(asio::error::would_block);
+}
+
+ASIO_TEST_SUITE
+(
+ "error",
+ ASIO_TEST_CASE(error_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/execution_context.cpp b/3rdparty/asio/src/tests/unit/execution_context.cpp
new file mode 100644
index 00000000000..802c483be41
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/execution_context.cpp
@@ -0,0 +1,25 @@
+//
+// execution_context.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/execution_context.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "execution_context",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/executor.cpp b/3rdparty/asio/src/tests/unit/executor.cpp
new file mode 100644
index 00000000000..493e363c1b3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/executor.cpp
@@ -0,0 +1,25 @@
+//
+// executor.cpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/executor.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "executor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/executor_work_guard.cpp b/3rdparty/asio/src/tests/unit/executor_work_guard.cpp
new file mode 100644
index 00000000000..ac62bc5427d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/executor_work_guard.cpp
@@ -0,0 +1,25 @@
+//
+// executor_work_guard.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/executor_work_guard.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "executor_work_guard",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/generic/.gitignore b/3rdparty/asio/src/tests/unit/generic/.gitignore
new file mode 100644
index 00000000000..c0571443308
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/.gitignore
@@ -0,0 +1,14 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+basic_endpoint
+datagram_protocol
+raw_protocol
+seq_packet_protocol
+stream_protocol
diff --git a/3rdparty/asio/src/tests/unit/generic/basic_endpoint.cpp b/3rdparty/asio/src/tests/unit/generic/basic_endpoint.cpp
new file mode 100644
index 00000000000..ef6d2b1b82f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/basic_endpoint.cpp
@@ -0,0 +1,25 @@
+//
+// generic/basic_endpoint.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "generic/basic_endpoint",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/generic/datagram_protocol.cpp b/3rdparty/asio/src/tests/unit/generic/datagram_protocol.cpp
new file mode 100644
index 00000000000..32f636ba0c7
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/datagram_protocol.cpp
@@ -0,0 +1,267 @@
+//
+// generic/datagram_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/datagram_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "asio/ip/udp.hpp"
+#include "../unit_test.hpp"
+
+#if defined(__cplusplus_cli) || defined(__cplusplus_winrt)
+# define generic cpp_generic
+#endif
+
+//------------------------------------------------------------------------------
+
+// generic_datagram_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::datagram_socket::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_datagram_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+ using namespace asio;
+ namespace generic = asio::generic;
+ typedef generic::datagram_protocol dp;
+
+ const int af_inet = ASIO_OS_DEF(AF_INET);
+ const int ipproto_udp = ASIO_OS_DEF(IPPROTO_UDP);
+ const int sock_dgram = ASIO_OS_DEF(SOCK_DGRAM);
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ socket_base::send_buffer_size socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_datagram_socket constructors.
+
+ dp::socket socket1(ioc);
+ dp::socket socket2(ioc, dp(af_inet, ipproto_udp));
+ dp::socket socket3(ioc, dp::endpoint());
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ dp::socket::native_handle_type native_socket1
+ = ::socket(af_inet, sock_dgram, 0);
+ dp::socket socket4(ioc, dp(af_inet, ipproto_udp), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ dp::socket socket5(std::move(socket4));
+ asio::ip::udp::socket udp_socket(ioc);
+ dp::socket socket6(std::move(udp_socket));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = dp::socket(ioc);
+ socket1 = std::move(socket2);
+ socket1 = asio::ip::udp::socket(ioc);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+ dp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = socket1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_socket functions.
+
+ dp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(dp(af_inet, ipproto_udp));
+ socket1.open(dp(af_inet, ipproto_udp), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ dp::socket::native_handle_type native_socket2
+ = ::socket(af_inet, sock_dgram, 0);
+ socket1.assign(dp(af_inet, ipproto_udp), native_socket2);
+ dp::socket::native_handle_type native_socket3
+ = ::socket(af_inet, sock_dgram, 0);
+ socket1.assign(dp(af_inet, ipproto_udp), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ dp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(dp::endpoint());
+ socket1.bind(dp::endpoint(), ec);
+
+ socket1.connect(dp::endpoint());
+ socket1.connect(dp::endpoint(), ec);
+
+ socket1.async_connect(dp::endpoint(), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ dp::endpoint endpoint1 = socket1.local_endpoint();
+ dp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ dp::endpoint endpoint3 = socket1.remote_endpoint();
+ dp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_datagram_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler);
+ socket1.async_send(buffer(const_char_buffer), send_handler);
+ socket1.async_send(null_buffers(), send_handler);
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint());
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint());
+ socket1.send_to(null_buffers(),
+ dp::endpoint());
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint(), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint(), in_flags);
+ socket1.send_to(null_buffers(),
+ dp::endpoint(), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint(), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint(), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ dp::endpoint(), in_flags, ec);
+
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ dp::endpoint(), send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ dp::endpoint(), send_handler);
+ socket1.async_send_to(null_buffers(),
+ dp::endpoint(), send_handler);
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ dp::endpoint(), in_flags, send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ dp::endpoint(), in_flags, send_handler);
+ socket1.async_send_to(null_buffers(),
+ dp::endpoint(), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+ socket1.async_receive(null_buffers(), receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+ dp::endpoint endpoint;
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+ socket1.receive_from(null_buffers(), endpoint);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+ socket1.receive_from(null_buffers(), endpoint, in_flags);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+ socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, receive_handler);
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, receive_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace generic_datagram_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "generic/datagram_protocol",
+ ASIO_TEST_CASE(generic_datagram_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/generic/raw_protocol.cpp b/3rdparty/asio/src/tests/unit/generic/raw_protocol.cpp
new file mode 100644
index 00000000000..92c0efa899f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/raw_protocol.cpp
@@ -0,0 +1,267 @@
+//
+// generic/raw_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/raw_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "asio/ip/icmp.hpp"
+#include "../unit_test.hpp"
+
+#if defined(__cplusplus_cli) || defined(__cplusplus_winrt)
+# define generic cpp_generic
+#endif
+
+//------------------------------------------------------------------------------
+
+// generic_raw_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::raw_socket::socket compile and link correctly. Runtime failures
+// are ignored.
+
+namespace generic_raw_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+ using namespace asio;
+ namespace generic = asio::generic;
+ typedef generic::raw_protocol rp;
+
+ const int af_inet = ASIO_OS_DEF(AF_INET);
+ const int ipproto_icmp = ASIO_OS_DEF(IPPROTO_ICMP);
+ const int sock_raw = ASIO_OS_DEF(SOCK_RAW);
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ socket_base::send_buffer_size socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_raw_socket constructors.
+
+ rp::socket socket1(ioc);
+ rp::socket socket2(ioc, rp(af_inet, ipproto_icmp));
+ rp::socket socket3(ioc, rp::endpoint());
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ rp::socket::native_handle_type native_socket1
+ = ::socket(af_inet, sock_raw, 0);
+ rp::socket socket4(ioc, rp(af_inet, ipproto_icmp), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ rp::socket socket5(std::move(socket4));
+ asio::ip::icmp::socket icmp_socket(ioc);
+ rp::socket socket6(std::move(icmp_socket));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = rp::socket(ioc);
+ socket1 = std::move(socket2);
+ socket1 = asio::ip::icmp::socket(ioc);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+ rp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = socket1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_socket functions.
+
+ rp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(rp(af_inet, ipproto_icmp));
+ socket1.open(rp(af_inet, ipproto_icmp), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ rp::socket::native_handle_type native_socket2
+ = ::socket(af_inet, sock_raw, 0);
+ socket1.assign(rp(af_inet, ipproto_icmp), native_socket2);
+ rp::socket::native_handle_type native_socket3
+ = ::socket(af_inet, sock_raw, 0);
+ socket1.assign(rp(af_inet, ipproto_icmp), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ rp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(rp::endpoint());
+ socket1.bind(rp::endpoint(), ec);
+
+ socket1.connect(rp::endpoint());
+ socket1.connect(rp::endpoint(), ec);
+
+ socket1.async_connect(rp::endpoint(), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ rp::endpoint endpoint1 = socket1.local_endpoint();
+ rp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ rp::endpoint endpoint3 = socket1.remote_endpoint();
+ rp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_raw_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler);
+ socket1.async_send(buffer(const_char_buffer), send_handler);
+ socket1.async_send(null_buffers(), send_handler);
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.send_to(buffer(mutable_char_buffer),
+ rp::endpoint());
+ socket1.send_to(buffer(const_char_buffer),
+ rp::endpoint());
+ socket1.send_to(null_buffers(),
+ rp::endpoint());
+ socket1.send_to(buffer(mutable_char_buffer),
+ rp::endpoint(), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ rp::endpoint(), in_flags);
+ socket1.send_to(null_buffers(),
+ rp::endpoint(), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ rp::endpoint(), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ rp::endpoint(), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ rp::endpoint(), in_flags, ec);
+
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ rp::endpoint(), send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ rp::endpoint(), send_handler);
+ socket1.async_send_to(null_buffers(),
+ rp::endpoint(), send_handler);
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ rp::endpoint(), in_flags, send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ rp::endpoint(), in_flags, send_handler);
+ socket1.async_send_to(null_buffers(),
+ rp::endpoint(), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+ socket1.async_receive(null_buffers(), receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+ rp::endpoint endpoint;
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+ socket1.receive_from(null_buffers(), endpoint);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+ socket1.receive_from(null_buffers(), endpoint, in_flags);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+ socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, receive_handler);
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, receive_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace generic_raw_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "generic/raw_protocol",
+ ASIO_TEST_CASE(generic_raw_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/generic/seq_packet_protocol.cpp b/3rdparty/asio/src/tests/unit/generic/seq_packet_protocol.cpp
new file mode 100644
index 00000000000..e66012649b4
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/seq_packet_protocol.cpp
@@ -0,0 +1,209 @@
+//
+// generic/seq_packet_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/seq_packet_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "../unit_test.hpp"
+
+#if defined(__cplusplus_cli) || defined(__cplusplus_winrt)
+# define generic cpp_generic
+#endif
+
+//------------------------------------------------------------------------------
+
+// generic_seq_packet_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::seq_packet_socket::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_seq_packet_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+ using namespace asio;
+ namespace generic = asio::generic;
+ typedef generic::seq_packet_protocol spp;
+
+ const int af_inet = ASIO_OS_DEF(AF_INET);
+ const int sock_seqpacket = ASIO_OS_DEF(SOCK_SEQPACKET);
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ const socket_base::message_flags in_flags = 0;
+ socket_base::message_flags out_flags = 0;
+ socket_base::send_buffer_size socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_seq_packet_socket constructors.
+
+ spp::socket socket1(ioc);
+ spp::socket socket2(ioc, spp(af_inet, 0));
+ spp::socket socket3(ioc, spp::endpoint());
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ spp::socket::native_handle_type native_socket1
+ = ::socket(af_inet, sock_seqpacket, 0);
+ spp::socket socket4(ioc, spp(af_inet, 0), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ spp::socket socket5(std::move(socket4));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_seq_packet_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = spp::socket(ioc);
+ socket1 = std::move(socket2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+ spp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = socket1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_socket functions.
+
+ spp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(spp(af_inet, 0));
+ socket1.open(spp(af_inet, 0), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ spp::socket::native_handle_type native_socket2
+ = ::socket(af_inet, sock_seqpacket, 0);
+ socket1.assign(spp(af_inet, 0), native_socket2);
+ spp::socket::native_handle_type native_socket3
+ = ::socket(af_inet, sock_seqpacket, 0);
+ socket1.assign(spp(af_inet, 0), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ spp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(spp::endpoint());
+ socket1.bind(spp::endpoint(), ec);
+
+ socket1.connect(spp::endpoint());
+ socket1.connect(spp::endpoint(), ec);
+
+ socket1.async_connect(spp::endpoint(), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ spp::endpoint endpoint1 = socket1.local_endpoint();
+ spp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ spp::endpoint endpoint3 = socket1.remote_endpoint();
+ spp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_seq_packet_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer), out_flags);
+ socket1.receive(null_buffers(), out_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags);
+ socket1.receive(null_buffers(), in_flags, out_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags, ec);
+ socket1.receive(null_buffers(), in_flags, out_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), out_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), out_flags, receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ out_flags, receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, out_flags, receive_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace generic_seq_packet_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "generic/seq_packet_protocol",
+ ASIO_TEST_CASE(generic_seq_packet_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/generic/stream_protocol.cpp b/3rdparty/asio/src/tests/unit/generic/stream_protocol.cpp
new file mode 100644
index 00000000000..796206917c6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/generic/stream_protocol.cpp
@@ -0,0 +1,252 @@
+//
+// generic/stream_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/stream_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "../unit_test.hpp"
+
+#if defined(__cplusplus_cli) || defined(__cplusplus_winrt)
+# define generic cpp_generic
+#endif
+
+//------------------------------------------------------------------------------
+
+// generic_stream_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::stream_protocol::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_stream_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+ using namespace asio;
+ namespace generic = asio::generic;
+ typedef generic::stream_protocol sp;
+
+ const int af_inet = ASIO_OS_DEF(AF_INET);
+ const int ipproto_tcp = ASIO_OS_DEF(IPPROTO_TCP);
+ const int sock_stream = ASIO_OS_DEF(SOCK_STREAM);
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ socket_base::keep_alive socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_stream_socket constructors.
+
+ sp::socket socket1(ioc);
+ sp::socket socket2(ioc, sp(af_inet, ipproto_tcp));
+ sp::socket socket3(ioc, sp::endpoint());
+#if defined(ASIO_WINDOWS_RUNTIME)
+ Windows::Networking::Sockets::StreamSocket^ native_socket1 = nullptr;
+#else // defined(ASIO_WINDOWS_RUNTIME)
+ sp::socket::native_handle_type native_socket1
+ = ::socket(af_inet, sock_stream, 0);
+#endif // defined(ASIO_WINDOWS_RUNTIME)
+ sp::socket socket4(ioc, sp(af_inet, ipproto_tcp), native_socket1);
+
+#if defined(ASIO_HAS_MOVE)
+ sp::socket socket5(std::move(socket4));
+ asio::ip::tcp::socket tcp_socket(ioc);
+ sp::socket socket6(std::move(tcp_socket));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_stream_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = sp::socket(ioc);
+ socket1 = std::move(socket2);
+ socket1 = asio::ip::tcp::socket(ioc);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+ sp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = socket1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_socket functions.
+
+ sp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(sp(af_inet, ipproto_tcp));
+ socket1.open(sp(af_inet, ipproto_tcp), ec);
+
+#if defined(ASIO_WINDOWS_RUNTIME)
+ Windows::Networking::Sockets::StreamSocket^ native_socket2 = nullptr;
+#else // defined(ASIO_WINDOWS_RUNTIME)
+ sp::socket::native_handle_type native_socket2
+ = ::socket(af_inet, sock_stream, 0);
+#endif // defined(ASIO_WINDOWS_RUNTIME)
+ socket1.assign(sp(af_inet, ipproto_tcp), native_socket2);
+#if defined(ASIO_WINDOWS_RUNTIME)
+ Windows::Networking::Sockets::StreamSocket^ native_socket3 = nullptr;
+#else // defined(ASIO_WINDOWS_RUNTIME)
+ sp::socket::native_handle_type native_socket3
+ = ::socket(af_inet, sock_stream, 0);
+#endif // defined(ASIO_WINDOWS_RUNTIME)
+ socket1.assign(sp(af_inet, ipproto_tcp), native_socket3, ec);
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ sp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(sp::endpoint());
+ socket1.bind(sp::endpoint(), ec);
+
+ socket1.connect(sp::endpoint());
+ socket1.connect(sp::endpoint(), ec);
+
+ socket1.async_connect(sp::endpoint(), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ sp::endpoint endpoint1 = socket1.local_endpoint();
+ sp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ sp::endpoint endpoint3 = socket1.remote_endpoint();
+ sp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_stream_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler);
+ socket1.async_send(buffer(const_char_buffer), send_handler);
+ socket1.async_send(null_buffers(), send_handler);
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+ socket1.async_receive(null_buffers(), receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+ socket1.write_some(buffer(mutable_char_buffer));
+ socket1.write_some(buffer(const_char_buffer));
+ socket1.write_some(null_buffers());
+ socket1.write_some(buffer(mutable_char_buffer), ec);
+ socket1.write_some(buffer(const_char_buffer), ec);
+ socket1.write_some(null_buffers(), ec);
+
+ socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
+ socket1.async_write_some(buffer(const_char_buffer), write_some_handler);
+ socket1.async_write_some(null_buffers(), write_some_handler);
+
+ socket1.read_some(buffer(mutable_char_buffer));
+ socket1.read_some(buffer(mutable_char_buffer), ec);
+ socket1.read_some(null_buffers(), ec);
+
+ socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+ socket1.async_read_some(null_buffers(), read_some_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace generic_stream_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "generic/stream_protocol",
+ ASIO_TEST_CASE(generic_stream_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/high_resolution_timer.cpp b/3rdparty/asio/src/tests/unit/high_resolution_timer.cpp
new file mode 100644
index 00000000000..894bd746474
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/high_resolution_timer.cpp
@@ -0,0 +1,30 @@
+//
+// high_resolution_timer.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Prevent link dependency on the Boost.System library.
+#if !defined(BOOST_SYSTEM_NO_DEPRECATED)
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif // !defined(BOOST_SYSTEM_NO_DEPRECATED)
+
+// Test that header file is self-contained.
+#include "asio/high_resolution_timer.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "high_resolution_timer",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/io_context.cpp b/3rdparty/asio/src/tests/unit/io_context.cpp
new file mode 100644
index 00000000000..530d1390e02
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/io_context.cpp
@@ -0,0 +1,362 @@
+//
+// io_context.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/io_context.hpp"
+
+#include <sstream>
+#include "asio/bind_executor.hpp"
+#include "asio/dispatch.hpp"
+#include "asio/post.hpp"
+#include "asio/thread.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+# include "asio/deadline_timer.hpp"
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+# include "asio/steady_timer.hpp"
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+using namespace asio;
+
+#if defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = std;
+#endif
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+typedef deadline_timer timer;
+namespace chronons = boost::posix_time;
+#elif defined(ASIO_HAS_CHRONO)
+typedef steady_timer timer;
+namespace chronons = asio::chrono;
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+
+void increment(int* count)
+{
+ ++(*count);
+}
+
+void decrement_to_zero(io_context* ioc, int* count)
+{
+ if (*count > 0)
+ {
+ --(*count);
+
+ int before_value = *count;
+ asio::post(*ioc, bindns::bind(decrement_to_zero, ioc, count));
+
+ // Handler execution cannot nest, so count value should remain unchanged.
+ ASIO_CHECK(*count == before_value);
+ }
+}
+
+void nested_decrement_to_zero(io_context* ioc, int* count)
+{
+ if (*count > 0)
+ {
+ --(*count);
+
+ asio::dispatch(*ioc,
+ bindns::bind(nested_decrement_to_zero, ioc, count));
+
+ // Handler execution is nested, so count value should now be zero.
+ ASIO_CHECK(*count == 0);
+ }
+}
+
+void sleep_increment(io_context* ioc, int* count)
+{
+ timer t(*ioc, chronons::seconds(2));
+ t.wait();
+
+ if (++(*count) < 3)
+ asio::post(*ioc, bindns::bind(sleep_increment, ioc, count));
+}
+
+void start_sleep_increments(io_context* ioc, int* count)
+{
+ // Give all threads a chance to start.
+ timer t(*ioc, chronons::seconds(2));
+ t.wait();
+
+ // Start the first of three increments.
+ asio::post(*ioc, bindns::bind(sleep_increment, ioc, count));
+}
+
+void throw_exception()
+{
+ throw 1;
+}
+
+void io_context_run(io_context* ioc)
+{
+ ioc->run();
+}
+
+void io_context_test()
+{
+ io_context ioc;
+ int count = 0;
+
+ asio::post(ioc, bindns::bind(increment, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 1);
+
+ count = 0;
+ ioc.restart();
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, bindns::bind(increment, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 5);
+
+ count = 0;
+ ioc.restart();
+ executor_work_guard<io_context::executor_type> w = make_work_guard(ioc);
+ asio::post(ioc, bindns::bind(&io_context::stop, &ioc));
+ ASIO_CHECK(!ioc.stopped());
+ ioc.run();
+
+ // The only operation executed should have been to stop run().
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ ioc.restart();
+ asio::post(ioc, bindns::bind(increment, &count));
+ w.reset();
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 1);
+
+ count = 10;
+ ioc.restart();
+ asio::post(ioc, bindns::bind(decrement_to_zero, &ioc, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 10);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ count = 10;
+ ioc.restart();
+ asio::post(ioc, bindns::bind(nested_decrement_to_zero, &ioc, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 10);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ count = 10;
+ ioc.restart();
+ asio::dispatch(ioc,
+ bindns::bind(nested_decrement_to_zero, &ioc, &count));
+
+ // No handlers can be called until run() is called, even though nested
+ // delivery was specifically allowed in the previous call.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 10);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 0);
+
+ count = 0;
+ int count2 = 0;
+ ioc.restart();
+ ASIO_CHECK(!ioc.stopped());
+ asio::post(ioc, bindns::bind(start_sleep_increments, &ioc, &count));
+ asio::post(ioc, bindns::bind(start_sleep_increments, &ioc, &count2));
+ thread thread1(bindns::bind(io_context_run, &ioc));
+ thread thread2(bindns::bind(io_context_run, &ioc));
+ thread1.join();
+ thread2.join();
+
+ // The run() calls will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 3);
+ ASIO_CHECK(count2 == 3);
+
+ count = 10;
+ io_context ioc2;
+ asio::dispatch(ioc, asio::bind_executor(ioc2,
+ bindns::bind(decrement_to_zero, &ioc2, &count)));
+ ioc.restart();
+ ASIO_CHECK(!ioc.stopped());
+ ioc.run();
+
+ // No decrement_to_zero handlers can be called until run() is called on the
+ // second io_context object.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 10);
+
+ ioc2.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(count == 0);
+
+ count = 0;
+ int exception_count = 0;
+ ioc.restart();
+ asio::post(ioc, &throw_exception);
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, bindns::bind(increment, &count));
+ asio::post(ioc, &throw_exception);
+ asio::post(ioc, bindns::bind(increment, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(!ioc.stopped());
+ ASIO_CHECK(count == 0);
+ ASIO_CHECK(exception_count == 0);
+
+ for (;;)
+ {
+ try
+ {
+ ioc.run();
+ break;
+ }
+ catch (int)
+ {
+ ++exception_count;
+ }
+ }
+
+ // The run() calls will not return until all work has finished.
+ ASIO_CHECK(ioc.stopped());
+ ASIO_CHECK(count == 3);
+ ASIO_CHECK(exception_count == 2);
+}
+
+class test_service : public asio::io_context::service
+{
+public:
+ static asio::io_context::id id;
+ test_service(asio::io_context& s)
+ : asio::io_context::service(s) {}
+private:
+ virtual void shutdown_service() {}
+};
+
+asio::io_context::id test_service::id;
+
+void io_context_service_test()
+{
+ asio::io_context ioc1;
+ asio::io_context ioc2;
+ asio::io_context ioc3;
+
+ // Implicit service registration.
+
+ asio::use_service<test_service>(ioc1);
+
+ ASIO_CHECK(asio::has_service<test_service>(ioc1));
+
+ test_service* svc1 = new test_service(ioc1);
+ try
+ {
+ asio::add_service(ioc1, svc1);
+ ASIO_ERROR("add_service did not throw");
+ }
+ catch (asio::service_already_exists&)
+ {
+ }
+ delete svc1;
+
+ // Explicit service registration.
+
+ test_service* svc2 = new test_service(ioc2);
+ asio::add_service(ioc2, svc2);
+
+ ASIO_CHECK(asio::has_service<test_service>(ioc2));
+ ASIO_CHECK(&asio::use_service<test_service>(ioc2) == svc2);
+
+ test_service* svc3 = new test_service(ioc2);
+ try
+ {
+ asio::add_service(ioc2, svc3);
+ ASIO_ERROR("add_service did not throw");
+ }
+ catch (asio::service_already_exists&)
+ {
+ }
+ delete svc3;
+
+ // Explicit registration with invalid owner.
+
+ test_service* svc4 = new test_service(ioc2);
+ try
+ {
+ asio::add_service(ioc3, svc4);
+ ASIO_ERROR("add_service did not throw");
+ }
+ catch (asio::invalid_service_owner&)
+ {
+ }
+ delete svc4;
+
+ ASIO_CHECK(!asio::has_service<test_service>(ioc3));
+}
+
+ASIO_TEST_SUITE
+(
+ "io_context",
+ ASIO_TEST_CASE(io_context_test)
+ ASIO_TEST_CASE(io_context_service_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/.gitignore b/3rdparty/asio/src/tests/unit/ip/.gitignore
new file mode 100644
index 00000000000..087ad80f192
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/.gitignore
@@ -0,0 +1,28 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+address
+address_v4*
+address_v6*
+basic_endpoint
+basic_resolver
+basic_resolver_entry
+basic_resolver_iterator
+basic_resolver_query
+host_name
+icmp
+multicast
+network_v4
+network_v6
+resolver_query_base
+resolver_service
+tcp
+udp
+unicast
+v6_only
diff --git a/3rdparty/asio/src/tests/unit/ip/address.cpp b/3rdparty/asio/src/tests/unit/ip/address.cpp
new file mode 100644
index 00000000000..e0b61d92b8d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address.cpp
@@ -0,0 +1,144 @@
+//
+// address.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address.hpp"
+
+#include "../unit_test.hpp"
+#include <sstream>
+
+//------------------------------------------------------------------------------
+
+// ip_address_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::address compile and link correctly. Runtime failures are ignored.
+
+namespace ip_address_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ // address constructors.
+
+ ip::address addr1;
+ const ip::address_v4 const_addr_v4;
+ ip::address addr2(const_addr_v4);
+ const ip::address_v6 const_addr_v6;
+ ip::address addr3(const_addr_v6);
+
+ // address functions.
+
+ bool b = addr1.is_v4();
+ (void)b;
+
+ b = addr1.is_v6();
+ (void)b;
+
+ b = addr1.is_loopback();
+ (void)b;
+
+ b = addr1.is_unspecified();
+ (void)b;
+
+ b = addr1.is_multicast();
+ (void)b;
+
+ ip::address_v4 addr_v4_value = addr1.to_v4();
+ (void)addr_v4_value;
+
+ ip::address_v6 addr_v6_value = addr1.to_v6();
+ (void)addr_v6_value;
+
+ std::string string_value = addr1.to_string();
+#if !defined(ASIO_NO_DEPRECATED)
+ string_value = addr1.to_string(ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address static functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::address::from_string("127.0.0.1");
+ addr1 = ip::address::from_string("127.0.0.1", ec);
+ addr1 = ip::address::from_string(string_value);
+ addr1 = ip::address::from_string(string_value, ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address comparisons.
+
+ b = (addr1 == addr2);
+ (void)b;
+
+ b = (addr1 != addr2);
+ (void)b;
+
+ b = (addr1 < addr2);
+ (void)b;
+
+ b = (addr1 > addr2);
+ (void)b;
+
+ b = (addr1 <= addr2);
+ (void)b;
+
+ b = (addr1 >= addr2);
+ (void)b;
+
+ // address creation functions.
+
+ addr1 = ip::make_address("127.0.0.1");
+ addr1 = ip::make_address("127.0.0.1", ec);
+ addr1 = ip::make_address(string_value);
+ addr1 = ip::make_address(string_value, ec);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_value("127.0.0.1");
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_value("127.0.0.1");
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ addr1 = ip::make_address(string_view_value);
+ addr1 = ip::make_address(string_view_value, ec);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // address I/O.
+
+ std::ostringstream os;
+ os << addr1;
+
+#if !defined(BOOST_NO_STD_WSTREAMBUF)
+ std::wostringstream wos;
+ wos << addr1;
+#endif // !defined(BOOST_NO_STD_WSTREAMBUF)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_address_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address",
+ ASIO_TEST_CASE(ip_address_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v4.cpp b/3rdparty/asio/src/tests/unit/ip/address_v4.cpp
new file mode 100644
index 00000000000..e65f12b06a1
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v4.cpp
@@ -0,0 +1,324 @@
+//
+// address_v4.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v4.hpp"
+
+#include "../unit_test.hpp"
+#include <sstream>
+
+//------------------------------------------------------------------------------
+
+// ip_address_v4_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::address_v4 compile and link correctly. Runtime failures are ignored.
+
+namespace ip_address_v4_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ // address_v4 constructors.
+
+ ip::address_v4 addr1;
+ const ip::address_v4::bytes_type const_bytes_value = { { 127, 0, 0, 1 } };
+ ip::address_v4 addr2(const_bytes_value);
+ const unsigned long const_ulong_value = 0x7F000001;
+ ip::address_v4 addr3(const_ulong_value);
+
+ // address_v4 functions.
+
+ bool b = addr1.is_loopback();
+ (void)b;
+
+ b = addr1.is_unspecified();
+ (void)b;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ b = addr1.is_class_a();
+ (void)b;
+
+ b = addr1.is_class_b();
+ (void)b;
+
+ b = addr1.is_class_c();
+ (void)b;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ b = addr1.is_multicast();
+ (void)b;
+
+ ip::address_v4::bytes_type bytes_value = addr1.to_bytes();
+ (void)bytes_value;
+
+ ip::address_v4::uint_type uint_value = addr1.to_uint();
+ (void)uint_value;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ unsigned long ulong_value = addr1.to_ulong();
+ (void)ulong_value;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ std::string string_value = addr1.to_string();
+#if !defined(ASIO_NO_DEPRECATED)
+ string_value = addr1.to_string(ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address_v4 static functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::address_v4::from_string("127.0.0.1");
+ addr1 = ip::address_v4::from_string("127.0.0.1", ec);
+ addr1 = ip::address_v4::from_string(string_value);
+ addr1 = ip::address_v4::from_string(string_value, ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ addr1 = ip::address_v4::any();
+
+ addr1 = ip::address_v4::loopback();
+
+ addr1 = ip::address_v4::broadcast();
+
+#if !defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::address_v4::broadcast(addr2, addr3);
+
+ addr1 = ip::address_v4::netmask(addr2);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address_v4 comparisons.
+
+ b = (addr1 == addr2);
+ (void)b;
+
+ b = (addr1 != addr2);
+ (void)b;
+
+ b = (addr1 < addr2);
+ (void)b;
+
+ b = (addr1 > addr2);
+ (void)b;
+
+ b = (addr1 <= addr2);
+ (void)b;
+
+ b = (addr1 >= addr2);
+ (void)b;
+
+ // address_v4 creation functions.
+
+ addr1 = ip::make_address_v4(const_bytes_value);
+ addr1 = ip::make_address_v4(const_ulong_value);
+ addr1 = ip::make_address_v4("127.0.0.1");
+ addr1 = ip::make_address_v4("127.0.0.1", ec);
+ addr1 = ip::make_address_v4(string_value);
+ addr1 = ip::make_address_v4(string_value, ec);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_value("127.0.0.1");
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_value("127.0.0.1");
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ addr1 = ip::make_address_v4(string_view_value);
+ addr1 = ip::make_address_v4(string_view_value, ec);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // address_v4 I/O.
+
+ std::ostringstream os;
+ os << addr1;
+
+#if !defined(BOOST_NO_STD_WSTREAMBUF)
+ std::wostringstream wos;
+ wos << addr1;
+#endif // !defined(BOOST_NO_STD_WSTREAMBUF)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_address_v4_compile
+
+//------------------------------------------------------------------------------
+
+// ip_address_v4_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that the various public member functions meet the
+// necessary postconditions.
+
+namespace ip_address_v4_runtime {
+
+void test()
+{
+ using asio::ip::address_v4;
+
+ address_v4 a1;
+ ASIO_CHECK(a1.to_bytes()[0] == 0);
+ ASIO_CHECK(a1.to_bytes()[1] == 0);
+ ASIO_CHECK(a1.to_bytes()[2] == 0);
+ ASIO_CHECK(a1.to_bytes()[3] == 0);
+ ASIO_CHECK(a1.to_uint() == 0);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(a1.to_ulong() == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ address_v4::bytes_type b1 = {{ 1, 2, 3, 4 }};
+ address_v4 a2(b1);
+ ASIO_CHECK(a2.to_bytes()[0] == 1);
+ ASIO_CHECK(a2.to_bytes()[1] == 2);
+ ASIO_CHECK(a2.to_bytes()[2] == 3);
+ ASIO_CHECK(a2.to_bytes()[3] == 4);
+ ASIO_CHECK(((a2.to_uint() >> 24) & 0xFF) == b1[0]);
+ ASIO_CHECK(((a2.to_uint() >> 16) & 0xFF) == b1[1]);
+ ASIO_CHECK(((a2.to_uint() >> 8) & 0xFF) == b1[2]);
+ ASIO_CHECK((a2.to_uint() & 0xFF) == b1[3]);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(((a2.to_ulong() >> 24) & 0xFF) == b1[0]);
+ ASIO_CHECK(((a2.to_ulong() >> 16) & 0xFF) == b1[1]);
+ ASIO_CHECK(((a2.to_ulong() >> 8) & 0xFF) == b1[2]);
+ ASIO_CHECK((a2.to_ulong() & 0xFF) == b1[3]);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ address_v4 a3(0x01020304);
+ ASIO_CHECK(a3.to_bytes()[0] == 1);
+ ASIO_CHECK(a3.to_bytes()[1] == 2);
+ ASIO_CHECK(a3.to_bytes()[2] == 3);
+ ASIO_CHECK(a3.to_bytes()[3] == 4);
+ ASIO_CHECK(a3.to_uint() == 0x01020304);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(a3.to_ulong() == 0x01020304);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ASIO_CHECK(address_v4(0x7F000001).is_loopback());
+ ASIO_CHECK(address_v4(0x7F000002).is_loopback());
+ ASIO_CHECK(!address_v4(0x00000000).is_loopback());
+ ASIO_CHECK(!address_v4(0x01020304).is_loopback());
+
+ ASIO_CHECK(address_v4(0x00000000).is_unspecified());
+ ASIO_CHECK(!address_v4(0x7F000001).is_unspecified());
+ ASIO_CHECK(!address_v4(0x01020304).is_unspecified());
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(address_v4(0x01000000).is_class_a());
+ ASIO_CHECK(address_v4(0x7F000000).is_class_a());
+ ASIO_CHECK(!address_v4(0x80000000).is_class_a());
+ ASIO_CHECK(!address_v4(0xBFFF0000).is_class_a());
+ ASIO_CHECK(!address_v4(0xC0000000).is_class_a());
+ ASIO_CHECK(!address_v4(0xDFFFFF00).is_class_a());
+ ASIO_CHECK(!address_v4(0xE0000000).is_class_a());
+ ASIO_CHECK(!address_v4(0xEFFFFFFF).is_class_a());
+ ASIO_CHECK(!address_v4(0xF0000000).is_class_a());
+ ASIO_CHECK(!address_v4(0xFFFFFFFF).is_class_a());
+
+ ASIO_CHECK(!address_v4(0x01000000).is_class_b());
+ ASIO_CHECK(!address_v4(0x7F000000).is_class_b());
+ ASIO_CHECK(address_v4(0x80000000).is_class_b());
+ ASIO_CHECK(address_v4(0xBFFF0000).is_class_b());
+ ASIO_CHECK(!address_v4(0xC0000000).is_class_b());
+ ASIO_CHECK(!address_v4(0xDFFFFF00).is_class_b());
+ ASIO_CHECK(!address_v4(0xE0000000).is_class_b());
+ ASIO_CHECK(!address_v4(0xEFFFFFFF).is_class_b());
+ ASIO_CHECK(!address_v4(0xF0000000).is_class_b());
+ ASIO_CHECK(!address_v4(0xFFFFFFFF).is_class_b());
+
+ ASIO_CHECK(!address_v4(0x01000000).is_class_c());
+ ASIO_CHECK(!address_v4(0x7F000000).is_class_c());
+ ASIO_CHECK(!address_v4(0x80000000).is_class_c());
+ ASIO_CHECK(!address_v4(0xBFFF0000).is_class_c());
+ ASIO_CHECK(address_v4(0xC0000000).is_class_c());
+ ASIO_CHECK(address_v4(0xDFFFFF00).is_class_c());
+ ASIO_CHECK(!address_v4(0xE0000000).is_class_c());
+ ASIO_CHECK(!address_v4(0xEFFFFFFF).is_class_c());
+ ASIO_CHECK(!address_v4(0xF0000000).is_class_c());
+ ASIO_CHECK(!address_v4(0xFFFFFFFF).is_class_c());
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ASIO_CHECK(!address_v4(0x01000000).is_multicast());
+ ASIO_CHECK(!address_v4(0x7F000000).is_multicast());
+ ASIO_CHECK(!address_v4(0x80000000).is_multicast());
+ ASIO_CHECK(!address_v4(0xBFFF0000).is_multicast());
+ ASIO_CHECK(!address_v4(0xC0000000).is_multicast());
+ ASIO_CHECK(!address_v4(0xDFFFFF00).is_multicast());
+ ASIO_CHECK(address_v4(0xE0000000).is_multicast());
+ ASIO_CHECK(address_v4(0xEFFFFFFF).is_multicast());
+ ASIO_CHECK(!address_v4(0xF0000000).is_multicast());
+ ASIO_CHECK(!address_v4(0xFFFFFFFF).is_multicast());
+
+ address_v4 a4 = address_v4::any();
+ ASIO_CHECK(a4.to_bytes()[0] == 0);
+ ASIO_CHECK(a4.to_bytes()[1] == 0);
+ ASIO_CHECK(a4.to_bytes()[2] == 0);
+ ASIO_CHECK(a4.to_bytes()[3] == 0);
+ ASIO_CHECK(a4.to_uint() == 0);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(a4.to_ulong() == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ address_v4 a5 = address_v4::loopback();
+ ASIO_CHECK(a5.to_bytes()[0] == 0x7F);
+ ASIO_CHECK(a5.to_bytes()[1] == 0);
+ ASIO_CHECK(a5.to_bytes()[2] == 0);
+ ASIO_CHECK(a5.to_bytes()[3] == 0x01);
+ ASIO_CHECK(a5.to_uint() == 0x7F000001);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(a5.to_ulong() == 0x7F000001);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ address_v4 a6 = address_v4::broadcast();
+ ASIO_CHECK(a6.to_bytes()[0] == 0xFF);
+ ASIO_CHECK(a6.to_bytes()[1] == 0xFF);
+ ASIO_CHECK(a6.to_bytes()[2] == 0xFF);
+ ASIO_CHECK(a6.to_bytes()[3] == 0xFF);
+ ASIO_CHECK(a6.to_uint() == 0xFFFFFFFF);
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(a6.to_ulong() == 0xFFFFFFFF);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+#if !defined(ASIO_NO_DEPRECATED)
+ address_v4 class_a_net(0xFF000000);
+ address_v4 class_b_net(0xFFFF0000);
+ address_v4 class_c_net(0xFFFFFF00);
+ address_v4 other_net(0xFFFFFFFF);
+ ASIO_CHECK(address_v4::netmask(address_v4(0x01000000)) == class_a_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0x7F000000)) == class_a_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0x80000000)) == class_b_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xBFFF0000)) == class_b_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xC0000000)) == class_c_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xDFFFFF00)) == class_c_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xE0000000)) == other_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xEFFFFFFF)) == other_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xF0000000)) == other_net);
+ ASIO_CHECK(address_v4::netmask(address_v4(0xFFFFFFFF)) == other_net);
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+} // namespace ip_address_v4_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v4",
+ ASIO_TEST_CASE(ip_address_v4_compile::test)
+ ASIO_TEST_CASE(ip_address_v4_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v4_iterator.cpp b/3rdparty/asio/src/tests/unit/ip/address_v4_iterator.cpp
new file mode 100644
index 00000000000..f8917220d12
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v4_iterator.cpp
@@ -0,0 +1,27 @@
+//
+// address_v4_iterator.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v4_iterator.hpp"
+
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v4_iterator",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v4_range.cpp b/3rdparty/asio/src/tests/unit/ip/address_v4_range.cpp
new file mode 100644
index 00000000000..0eb652d0699
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v4_range.cpp
@@ -0,0 +1,27 @@
+//
+// address_v4_range.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v4_range.hpp"
+
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v4_range",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v6.cpp b/3rdparty/asio/src/tests/unit/ip/address_v6.cpp
new file mode 100644
index 00000000000..b73f65c1b2e
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v6.cpp
@@ -0,0 +1,409 @@
+//
+// address_v6.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v6.hpp"
+
+#include "../unit_test.hpp"
+#include <sstream>
+
+//------------------------------------------------------------------------------
+
+// ip_address_v6_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::address_v6 compile and link correctly. Runtime failures are ignored.
+
+namespace ip_address_v6_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ // address_v6 constructors.
+
+ ip::address_v6 addr1;
+ const ip::address_v6::bytes_type const_bytes_value = { { 0 } };
+ ip::address_v6 addr2(const_bytes_value);
+
+ // address_v6 functions.
+
+ unsigned long scope_id = addr1.scope_id();
+ addr1.scope_id(scope_id);
+
+ bool b = addr1.is_unspecified();
+ (void)b;
+
+ b = addr1.is_loopback();
+ (void)b;
+
+ b = addr1.is_multicast();
+ (void)b;
+
+ b = addr1.is_link_local();
+ (void)b;
+
+ b = addr1.is_site_local();
+ (void)b;
+
+ b = addr1.is_v4_mapped();
+ (void)b;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ b = addr1.is_v4_compatible();
+ (void)b;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ b = addr1.is_multicast_node_local();
+ (void)b;
+
+ b = addr1.is_multicast_link_local();
+ (void)b;
+
+ b = addr1.is_multicast_site_local();
+ (void)b;
+
+ b = addr1.is_multicast_org_local();
+ (void)b;
+
+ b = addr1.is_multicast_global();
+ (void)b;
+
+ ip::address_v6::bytes_type bytes_value = addr1.to_bytes();
+ (void)bytes_value;
+
+ std::string string_value = addr1.to_string();
+#if !defined(ASIO_NO_DEPRECATED)
+ string_value = addr1.to_string(ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::address_v4 addr3 = addr1.to_v4();
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address_v6 static functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::address_v6::from_string("0::0");
+ addr1 = ip::address_v6::from_string("0::0", ec);
+ addr1 = ip::address_v6::from_string(string_value);
+ addr1 = ip::address_v6::from_string(string_value, ec);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ addr1 = ip::address_v6::any();
+
+ addr1 = ip::address_v6::loopback();
+
+#if !defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::address_v6::v4_mapped(addr3);
+
+ addr1 = ip::address_v6::v4_compatible(addr3);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // address_v6 comparisons.
+
+ b = (addr1 == addr2);
+ (void)b;
+
+ b = (addr1 != addr2);
+ (void)b;
+
+ b = (addr1 < addr2);
+ (void)b;
+
+ b = (addr1 > addr2);
+ (void)b;
+
+ b = (addr1 <= addr2);
+ (void)b;
+
+ b = (addr1 >= addr2);
+ (void)b;
+
+ // address_v6 creation functions.
+
+ addr1 = ip::make_address_v6(const_bytes_value, scope_id);
+ addr1 = ip::make_address_v6("0::0");
+ addr1 = ip::make_address_v6("0::0", ec);
+ addr1 = ip::make_address_v6(string_value);
+ addr1 = ip::make_address_v6(string_value, ec);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_value("0::0");
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_value("0::0");
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ addr1 = ip::make_address_v6(string_view_value);
+ addr1 = ip::make_address_v6(string_view_value, ec);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // address_v6 IPv4-mapped conversion.
+#if defined(ASIO_NO_DEPRECATED)
+ ip::address_v4 addr3;
+#endif // defined(ASIO_NO_DEPRECATED)
+ addr1 = ip::make_address_v6(ip::v4_mapped, addr3);
+ addr3 = ip::make_address_v4(ip::v4_mapped, addr1);
+
+ // address_v6 I/O.
+
+ std::ostringstream os;
+ os << addr1;
+
+#if !defined(BOOST_NO_STD_WSTREAMBUF)
+ std::wostringstream wos;
+ wos << addr1;
+#endif // !defined(BOOST_NO_STD_WSTREAMBUF)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_address_v6_compile
+
+//------------------------------------------------------------------------------
+
+// ip_address_v6_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that the various public member functions meet the
+// necessary postconditions.
+
+namespace ip_address_v6_runtime {
+
+void test()
+{
+ using asio::ip::address_v6;
+
+ address_v6 a1;
+ ASIO_CHECK(a1.is_unspecified());
+ ASIO_CHECK(a1.scope_id() == 0);
+
+ address_v6::bytes_type b1 = {{ 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }};
+ address_v6 a2(b1, 12345);
+ ASIO_CHECK(a2.to_bytes()[0] == 1);
+ ASIO_CHECK(a2.to_bytes()[1] == 2);
+ ASIO_CHECK(a2.to_bytes()[2] == 3);
+ ASIO_CHECK(a2.to_bytes()[3] == 4);
+ ASIO_CHECK(a2.to_bytes()[4] == 5);
+ ASIO_CHECK(a2.to_bytes()[5] == 6);
+ ASIO_CHECK(a2.to_bytes()[6] == 7);
+ ASIO_CHECK(a2.to_bytes()[7] == 8);
+ ASIO_CHECK(a2.to_bytes()[8] == 9);
+ ASIO_CHECK(a2.to_bytes()[9] == 10);
+ ASIO_CHECK(a2.to_bytes()[10] == 11);
+ ASIO_CHECK(a2.to_bytes()[11] == 12);
+ ASIO_CHECK(a2.to_bytes()[12] == 13);
+ ASIO_CHECK(a2.to_bytes()[13] == 14);
+ ASIO_CHECK(a2.to_bytes()[14] == 15);
+ ASIO_CHECK(a2.to_bytes()[15] == 16);
+ ASIO_CHECK(a2.scope_id() == 12345);
+
+ address_v6 a3;
+ a3.scope_id(12345);
+ ASIO_CHECK(a3.scope_id() == 12345);
+
+ address_v6 unspecified_address;
+ address_v6::bytes_type loopback_bytes = {{ 0 }};
+ loopback_bytes[15] = 1;
+ address_v6 loopback_address(loopback_bytes);
+ address_v6::bytes_type link_local_bytes = {{ 0xFE, 0x80, 1 }};
+ address_v6 link_local_address(link_local_bytes);
+ address_v6::bytes_type site_local_bytes = {{ 0xFE, 0xC0, 1 }};
+ address_v6 site_local_address(site_local_bytes);
+ address_v6::bytes_type v4_mapped_bytes = {{ 0 }};
+ v4_mapped_bytes[10] = 0xFF, v4_mapped_bytes[11] = 0xFF;
+ v4_mapped_bytes[12] = 1, v4_mapped_bytes[13] = 2;
+ v4_mapped_bytes[14] = 3, v4_mapped_bytes[15] = 4;
+ address_v6 v4_mapped_address(v4_mapped_bytes);
+ address_v6::bytes_type v4_compat_bytes = {{ 0 }};
+ v4_compat_bytes[12] = 1, v4_compat_bytes[13] = 2;
+ v4_compat_bytes[14] = 3, v4_compat_bytes[15] = 4;
+ address_v6 v4_compat_address(v4_compat_bytes);
+ address_v6::bytes_type mcast_global_bytes = {{ 0xFF, 0x0E, 1 }};
+ address_v6 mcast_global_address(mcast_global_bytes);
+ address_v6::bytes_type mcast_link_local_bytes = {{ 0xFF, 0x02, 1 }};
+ address_v6 mcast_link_local_address(mcast_link_local_bytes);
+ address_v6::bytes_type mcast_node_local_bytes = {{ 0xFF, 0x01, 1 }};
+ address_v6 mcast_node_local_address(mcast_node_local_bytes);
+ address_v6::bytes_type mcast_org_local_bytes = {{ 0xFF, 0x08, 1 }};
+ address_v6 mcast_org_local_address(mcast_org_local_bytes);
+ address_v6::bytes_type mcast_site_local_bytes = {{ 0xFF, 0x05, 1 }};
+ address_v6 mcast_site_local_address(mcast_site_local_bytes);
+
+ ASIO_CHECK(!unspecified_address.is_loopback());
+ ASIO_CHECK(loopback_address.is_loopback());
+ ASIO_CHECK(!link_local_address.is_loopback());
+ ASIO_CHECK(!site_local_address.is_loopback());
+ ASIO_CHECK(!v4_mapped_address.is_loopback());
+ ASIO_CHECK(!v4_compat_address.is_loopback());
+ ASIO_CHECK(!mcast_global_address.is_loopback());
+ ASIO_CHECK(!mcast_link_local_address.is_loopback());
+ ASIO_CHECK(!mcast_node_local_address.is_loopback());
+ ASIO_CHECK(!mcast_org_local_address.is_loopback());
+ ASIO_CHECK(!mcast_site_local_address.is_loopback());
+
+ ASIO_CHECK(unspecified_address.is_unspecified());
+ ASIO_CHECK(!loopback_address.is_unspecified());
+ ASIO_CHECK(!link_local_address.is_unspecified());
+ ASIO_CHECK(!site_local_address.is_unspecified());
+ ASIO_CHECK(!v4_mapped_address.is_unspecified());
+ ASIO_CHECK(!v4_compat_address.is_unspecified());
+ ASIO_CHECK(!mcast_global_address.is_unspecified());
+ ASIO_CHECK(!mcast_link_local_address.is_unspecified());
+ ASIO_CHECK(!mcast_node_local_address.is_unspecified());
+ ASIO_CHECK(!mcast_org_local_address.is_unspecified());
+ ASIO_CHECK(!mcast_site_local_address.is_unspecified());
+
+ ASIO_CHECK(!unspecified_address.is_link_local());
+ ASIO_CHECK(!loopback_address.is_link_local());
+ ASIO_CHECK(link_local_address.is_link_local());
+ ASIO_CHECK(!site_local_address.is_link_local());
+ ASIO_CHECK(!v4_mapped_address.is_link_local());
+ ASIO_CHECK(!v4_compat_address.is_link_local());
+ ASIO_CHECK(!mcast_global_address.is_link_local());
+ ASIO_CHECK(!mcast_link_local_address.is_link_local());
+ ASIO_CHECK(!mcast_node_local_address.is_link_local());
+ ASIO_CHECK(!mcast_org_local_address.is_link_local());
+ ASIO_CHECK(!mcast_site_local_address.is_link_local());
+
+ ASIO_CHECK(!unspecified_address.is_site_local());
+ ASIO_CHECK(!loopback_address.is_site_local());
+ ASIO_CHECK(!link_local_address.is_site_local());
+ ASIO_CHECK(site_local_address.is_site_local());
+ ASIO_CHECK(!v4_mapped_address.is_site_local());
+ ASIO_CHECK(!v4_compat_address.is_site_local());
+ ASIO_CHECK(!mcast_global_address.is_site_local());
+ ASIO_CHECK(!mcast_link_local_address.is_site_local());
+ ASIO_CHECK(!mcast_node_local_address.is_site_local());
+ ASIO_CHECK(!mcast_org_local_address.is_site_local());
+ ASIO_CHECK(!mcast_site_local_address.is_site_local());
+
+ ASIO_CHECK(!unspecified_address.is_v4_mapped());
+ ASIO_CHECK(!loopback_address.is_v4_mapped());
+ ASIO_CHECK(!link_local_address.is_v4_mapped());
+ ASIO_CHECK(!site_local_address.is_v4_mapped());
+ ASIO_CHECK(v4_mapped_address.is_v4_mapped());
+ ASIO_CHECK(!v4_compat_address.is_v4_mapped());
+ ASIO_CHECK(!mcast_global_address.is_v4_mapped());
+ ASIO_CHECK(!mcast_link_local_address.is_v4_mapped());
+ ASIO_CHECK(!mcast_node_local_address.is_v4_mapped());
+ ASIO_CHECK(!mcast_org_local_address.is_v4_mapped());
+ ASIO_CHECK(!mcast_site_local_address.is_v4_mapped());
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ASIO_CHECK(!unspecified_address.is_v4_compatible());
+ ASIO_CHECK(!loopback_address.is_v4_compatible());
+ ASIO_CHECK(!link_local_address.is_v4_compatible());
+ ASIO_CHECK(!site_local_address.is_v4_compatible());
+ ASIO_CHECK(!v4_mapped_address.is_v4_compatible());
+ ASIO_CHECK(v4_compat_address.is_v4_compatible());
+ ASIO_CHECK(!mcast_global_address.is_v4_compatible());
+ ASIO_CHECK(!mcast_link_local_address.is_v4_compatible());
+ ASIO_CHECK(!mcast_node_local_address.is_v4_compatible());
+ ASIO_CHECK(!mcast_org_local_address.is_v4_compatible());
+ ASIO_CHECK(!mcast_site_local_address.is_v4_compatible());
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ASIO_CHECK(!unspecified_address.is_multicast());
+ ASIO_CHECK(!loopback_address.is_multicast());
+ ASIO_CHECK(!link_local_address.is_multicast());
+ ASIO_CHECK(!site_local_address.is_multicast());
+ ASIO_CHECK(!v4_mapped_address.is_multicast());
+ ASIO_CHECK(!v4_compat_address.is_multicast());
+ ASIO_CHECK(mcast_global_address.is_multicast());
+ ASIO_CHECK(mcast_link_local_address.is_multicast());
+ ASIO_CHECK(mcast_node_local_address.is_multicast());
+ ASIO_CHECK(mcast_org_local_address.is_multicast());
+ ASIO_CHECK(mcast_site_local_address.is_multicast());
+
+ ASIO_CHECK(!unspecified_address.is_multicast_global());
+ ASIO_CHECK(!loopback_address.is_multicast_global());
+ ASIO_CHECK(!link_local_address.is_multicast_global());
+ ASIO_CHECK(!site_local_address.is_multicast_global());
+ ASIO_CHECK(!v4_mapped_address.is_multicast_global());
+ ASIO_CHECK(!v4_compat_address.is_multicast_global());
+ ASIO_CHECK(mcast_global_address.is_multicast_global());
+ ASIO_CHECK(!mcast_link_local_address.is_multicast_global());
+ ASIO_CHECK(!mcast_node_local_address.is_multicast_global());
+ ASIO_CHECK(!mcast_org_local_address.is_multicast_global());
+ ASIO_CHECK(!mcast_site_local_address.is_multicast_global());
+
+ ASIO_CHECK(!unspecified_address.is_multicast_link_local());
+ ASIO_CHECK(!loopback_address.is_multicast_link_local());
+ ASIO_CHECK(!link_local_address.is_multicast_link_local());
+ ASIO_CHECK(!site_local_address.is_multicast_link_local());
+ ASIO_CHECK(!v4_mapped_address.is_multicast_link_local());
+ ASIO_CHECK(!v4_compat_address.is_multicast_link_local());
+ ASIO_CHECK(!mcast_global_address.is_multicast_link_local());
+ ASIO_CHECK(mcast_link_local_address.is_multicast_link_local());
+ ASIO_CHECK(!mcast_node_local_address.is_multicast_link_local());
+ ASIO_CHECK(!mcast_org_local_address.is_multicast_link_local());
+ ASIO_CHECK(!mcast_site_local_address.is_multicast_link_local());
+
+ ASIO_CHECK(!unspecified_address.is_multicast_node_local());
+ ASIO_CHECK(!loopback_address.is_multicast_node_local());
+ ASIO_CHECK(!link_local_address.is_multicast_node_local());
+ ASIO_CHECK(!site_local_address.is_multicast_node_local());
+ ASIO_CHECK(!v4_mapped_address.is_multicast_node_local());
+ ASIO_CHECK(!v4_compat_address.is_multicast_node_local());
+ ASIO_CHECK(!mcast_global_address.is_multicast_node_local());
+ ASIO_CHECK(!mcast_link_local_address.is_multicast_node_local());
+ ASIO_CHECK(mcast_node_local_address.is_multicast_node_local());
+ ASIO_CHECK(!mcast_org_local_address.is_multicast_node_local());
+ ASIO_CHECK(!mcast_site_local_address.is_multicast_node_local());
+
+ ASIO_CHECK(!unspecified_address.is_multicast_org_local());
+ ASIO_CHECK(!loopback_address.is_multicast_org_local());
+ ASIO_CHECK(!link_local_address.is_multicast_org_local());
+ ASIO_CHECK(!site_local_address.is_multicast_org_local());
+ ASIO_CHECK(!v4_mapped_address.is_multicast_org_local());
+ ASIO_CHECK(!v4_compat_address.is_multicast_org_local());
+ ASIO_CHECK(!mcast_global_address.is_multicast_org_local());
+ ASIO_CHECK(!mcast_link_local_address.is_multicast_org_local());
+ ASIO_CHECK(!mcast_node_local_address.is_multicast_org_local());
+ ASIO_CHECK(mcast_org_local_address.is_multicast_org_local());
+ ASIO_CHECK(!mcast_site_local_address.is_multicast_org_local());
+
+ ASIO_CHECK(!unspecified_address.is_multicast_site_local());
+ ASIO_CHECK(!loopback_address.is_multicast_site_local());
+ ASIO_CHECK(!link_local_address.is_multicast_site_local());
+ ASIO_CHECK(!site_local_address.is_multicast_site_local());
+ ASIO_CHECK(!v4_mapped_address.is_multicast_site_local());
+ ASIO_CHECK(!v4_compat_address.is_multicast_site_local());
+ ASIO_CHECK(!mcast_global_address.is_multicast_site_local());
+ ASIO_CHECK(!mcast_link_local_address.is_multicast_site_local());
+ ASIO_CHECK(!mcast_node_local_address.is_multicast_site_local());
+ ASIO_CHECK(!mcast_org_local_address.is_multicast_site_local());
+ ASIO_CHECK(mcast_site_local_address.is_multicast_site_local());
+
+ ASIO_CHECK(address_v6::loopback().is_loopback());
+}
+
+} // namespace ip_address_v6_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v6",
+ ASIO_TEST_CASE(ip_address_v6_compile::test)
+ ASIO_TEST_CASE(ip_address_v6_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v6_iterator.cpp b/3rdparty/asio/src/tests/unit/ip/address_v6_iterator.cpp
new file mode 100644
index 00000000000..16b040c7142
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v6_iterator.cpp
@@ -0,0 +1,27 @@
+//
+// address_v6_iterator.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v6_iterator.hpp"
+
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v6_iterator",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/address_v6_range.cpp b/3rdparty/asio/src/tests/unit/ip/address_v6_range.cpp
new file mode 100644
index 00000000000..76169234620
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/address_v6_range.cpp
@@ -0,0 +1,27 @@
+//
+// address_v6_range.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/address_v6_range.hpp"
+
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/address_v6_range",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/basic_endpoint.cpp b/3rdparty/asio/src/tests/unit/ip/basic_endpoint.cpp
new file mode 100644
index 00000000000..e363ef55661
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/basic_endpoint.cpp
@@ -0,0 +1,25 @@
+//
+// basic_endpoint.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/basic_endpoint.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/basic_endpoint",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/basic_resolver.cpp b/3rdparty/asio/src/tests/unit/ip/basic_resolver.cpp
new file mode 100644
index 00000000000..afe06f5e178
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/basic_resolver.cpp
@@ -0,0 +1,25 @@
+//
+// basic_resolver.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/basic_resolver.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/basic_resolver",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/basic_resolver_entry.cpp b/3rdparty/asio/src/tests/unit/ip/basic_resolver_entry.cpp
new file mode 100644
index 00000000000..2bebc825610
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/basic_resolver_entry.cpp
@@ -0,0 +1,25 @@
+//
+// basic_resolver_entry.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/basic_resolver_entry.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/basic_resolver_entry",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/basic_resolver_iterator.cpp b/3rdparty/asio/src/tests/unit/ip/basic_resolver_iterator.cpp
new file mode 100644
index 00000000000..9745e9eae00
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/basic_resolver_iterator.cpp
@@ -0,0 +1,25 @@
+//
+// basic_resolver_iterator.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/basic_resolver_iterator.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/basic_resolver_iterator",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/basic_resolver_query.cpp b/3rdparty/asio/src/tests/unit/ip/basic_resolver_query.cpp
new file mode 100644
index 00000000000..5fc5be4b150
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/basic_resolver_query.cpp
@@ -0,0 +1,25 @@
+//
+// basic_resolver_query.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/basic_resolver_query.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/basic_resolver_query",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/host_name.cpp b/3rdparty/asio/src/tests/unit/ip/host_name.cpp
new file mode 100644
index 00000000000..64dad204cdf
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/host_name.cpp
@@ -0,0 +1,55 @@
+//
+// host_name.cpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/host_name.hpp"
+
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// ip_host_name_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all host_name functions compile and link
+// correctly. Runtime failures are ignored.
+
+namespace ip_host_name_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ std::string host_name = ip::host_name();
+ std::string host_name2 = ip::host_name(ec);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_host_name_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/host_name",
+ ASIO_TEST_CASE(ip_host_name_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/icmp.cpp b/3rdparty/asio/src/tests/unit/ip/icmp.cpp
new file mode 100644
index 00000000000..4a4f5e843f3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/icmp.cpp
@@ -0,0 +1,684 @@
+//
+// icmp.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/icmp.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "asio/placeholders.hpp"
+#include "../unit_test.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../archetypes/deprecated_async_result.hpp"
+#include "../archetypes/gettable_socket_option.hpp"
+#include "../archetypes/io_control_command.hpp"
+#include "../archetypes/settable_socket_option.hpp"
+
+//------------------------------------------------------------------------------
+
+// ip_icmp_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::icmp::socket compile and link correctly. Runtime failures are ignored.
+
+namespace ip_icmp_socket_compile {
+
+struct connect_handler
+{
+ connect_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ connect_handler(connect_handler&&) {}
+private:
+ connect_handler(const connect_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct send_handler
+{
+ send_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ send_handler(send_handler&&) {}
+private:
+ send_handler(const send_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct receive_handler
+{
+ receive_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ receive_handler(receive_handler&&) {}
+private:
+ receive_handler(const receive_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ archetypes::settable_socket_option<void> settable_socket_option1;
+ archetypes::settable_socket_option<int> settable_socket_option2;
+ archetypes::settable_socket_option<double> settable_socket_option3;
+ archetypes::gettable_socket_option<void> gettable_socket_option1;
+ archetypes::gettable_socket_option<int> gettable_socket_option2;
+ archetypes::gettable_socket_option<double> gettable_socket_option3;
+ archetypes::io_control_command io_control_command;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+
+ // basic_datagram_socket constructors.
+
+ ip::icmp::socket socket1(ioc);
+ ip::icmp::socket socket2(ioc, ip::icmp::v4());
+ ip::icmp::socket socket3(ioc, ip::icmp::v6());
+ ip::icmp::socket socket4(ioc, ip::icmp::endpoint(ip::icmp::v4(), 0));
+ ip::icmp::socket socket5(ioc, ip::icmp::endpoint(ip::icmp::v6(), 0));
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::icmp::socket::native_handle_type native_socket1
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ ip::icmp::socket socket6(ioc, ip::icmp::v4(), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ ip::icmp::socket socket7(std::move(socket6));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = ip::icmp::socket(ioc);
+ socket1 = std::move(socket2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::icmp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+ // basic_socket functions.
+
+ ip::icmp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ const ip::icmp::socket& socket8 = socket1;
+ const ip::icmp::socket::lowest_layer_type& lowest_layer2
+ = socket8.lowest_layer();
+ (void)lowest_layer2;
+
+ socket1.open(ip::icmp::v4());
+ socket1.open(ip::icmp::v6());
+ socket1.open(ip::icmp::v4(), ec);
+ socket1.open(ip::icmp::v6(), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::icmp::socket::native_handle_type native_socket2
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ socket1.assign(ip::icmp::v4(), native_socket2);
+ ip::icmp::socket::native_handle_type native_socket3
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ socket1.assign(ip::icmp::v4(), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ ip::icmp::socket::native_handle_type native_socket4
+ = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(ip::icmp::endpoint(ip::icmp::v4(), 0));
+ socket1.bind(ip::icmp::endpoint(ip::icmp::v6(), 0));
+ socket1.bind(ip::icmp::endpoint(ip::icmp::v4(), 0), ec);
+ socket1.bind(ip::icmp::endpoint(ip::icmp::v6(), 0), ec);
+
+ socket1.connect(ip::icmp::endpoint(ip::icmp::v4(), 0));
+ socket1.connect(ip::icmp::endpoint(ip::icmp::v6(), 0));
+ socket1.connect(ip::icmp::endpoint(ip::icmp::v4(), 0), ec);
+ socket1.connect(ip::icmp::endpoint(ip::icmp::v6(), 0), ec);
+
+ socket1.async_connect(ip::icmp::endpoint(ip::icmp::v4(), 0),
+ connect_handler());
+ socket1.async_connect(ip::icmp::endpoint(ip::icmp::v6(), 0),
+ connect_handler());
+ int i1 = socket1.async_connect(ip::icmp::endpoint(ip::icmp::v4(), 0), lazy);
+ (void)i1;
+ int i2 = socket1.async_connect(ip::icmp::endpoint(ip::icmp::v6(), 0), lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d1 = socket1.async_connect(
+ ip::icmp::endpoint(ip::icmp::v4(), 0), dlazy);
+ (void)d1;
+ double d2 = socket1.async_connect(
+ ip::icmp::endpoint(ip::icmp::v6(), 0), dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.set_option(settable_socket_option1);
+ socket1.set_option(settable_socket_option1, ec);
+ socket1.set_option(settable_socket_option2);
+ socket1.set_option(settable_socket_option2, ec);
+ socket1.set_option(settable_socket_option3);
+ socket1.set_option(settable_socket_option3, ec);
+
+ socket1.get_option(gettable_socket_option1);
+ socket1.get_option(gettable_socket_option1, ec);
+ socket1.get_option(gettable_socket_option2);
+ socket1.get_option(gettable_socket_option2, ec);
+ socket1.get_option(gettable_socket_option3);
+ socket1.get_option(gettable_socket_option3, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ bool non_blocking1 = socket1.non_blocking();
+ (void)non_blocking1;
+ socket1.non_blocking(true);
+ socket1.non_blocking(false, ec);
+
+ bool non_blocking2 = socket1.native_non_blocking();
+ (void)non_blocking2;
+ socket1.native_non_blocking(true);
+ socket1.native_non_blocking(false, ec);
+
+ ip::icmp::endpoint endpoint1 = socket1.local_endpoint();
+ ip::icmp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ ip::icmp::endpoint endpoint3 = socket1.remote_endpoint();
+ ip::icmp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_datagram_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler());
+ socket1.async_send(buffer(const_char_buffer), send_handler());
+ socket1.async_send(null_buffers(), send_handler());
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler());
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler());
+ socket1.async_send(null_buffers(), in_flags, send_handler());
+ int i3 = socket1.async_send(buffer(mutable_char_buffer), lazy);
+ (void)i3;
+ int i4 = socket1.async_send(buffer(const_char_buffer), lazy);
+ (void)i4;
+ int i5 = socket1.async_send(null_buffers(), lazy);
+ (void)i5;
+ int i6 = socket1.async_send(buffer(mutable_char_buffer), in_flags, lazy);
+ (void)i6;
+ int i7 = socket1.async_send(buffer(const_char_buffer), in_flags, lazy);
+ (void)i7;
+ int i8 = socket1.async_send(null_buffers(), in_flags, lazy);
+ (void)i8;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = socket1.async_send(buffer(mutable_char_buffer), dlazy);
+ (void)d3;
+ double d4 = socket1.async_send(buffer(const_char_buffer), dlazy);
+ (void)d4;
+ double d5 = socket1.async_send(null_buffers(), dlazy);
+ (void)d5;
+ double d6 = socket1.async_send(
+ buffer(mutable_char_buffer), in_flags, dlazy);
+ (void)d6;
+ double d7 = socket1.async_send(buffer(const_char_buffer), in_flags, dlazy);
+ (void)d7;
+ double d8 = socket1.async_send(null_buffers(), in_flags, dlazy);
+ (void)d8;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0));
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0));
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0));
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0));
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0));
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0));
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags);
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags);
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, ec);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, ec);
+
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, send_handler());
+ int i9 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), lazy);
+ (void)i9;
+ int i10 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), lazy);
+ (void)i10;
+ int i11 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), lazy);
+ (void)i11;
+ int i12 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), lazy);
+ (void)i12;
+ int i13 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), lazy);
+ (void)i13;
+ int i14 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), lazy);
+ (void)i14;
+ int i15 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, lazy);
+ (void)i15;
+ int i16 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, lazy);
+ (void)i16;
+ int i17 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, lazy);
+ (void)i17;
+ int i18 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, lazy);
+ (void)i18;
+ int i19 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, lazy);
+ (void)i19;
+ int i20 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, lazy);
+ (void)i20;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d9 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), dlazy);
+ (void)d9;
+ double d10 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), dlazy);
+ (void)d10;
+ double d11 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), dlazy);
+ (void)d11;
+ double d12 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), dlazy);
+ (void)d12;
+ double d13 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), dlazy);
+ (void)d13;
+ double d14 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), dlazy);
+ (void)d14;
+ double d15 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, dlazy);
+ (void)d15;
+ double d16 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, dlazy);
+ (void)d16;
+ double d17 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, dlazy);
+ (void)d17;
+ double d18 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, dlazy);
+ (void)d18;
+ double d19 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v4(), 0), in_flags, dlazy);
+ (void)d19;
+ double d20 = socket1.async_send_to(null_buffers(),
+ ip::icmp::endpoint(ip::icmp::v6(), 0), in_flags, dlazy);
+ (void)d20;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler());
+ socket1.async_receive(null_buffers(), receive_handler());
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler());
+ socket1.async_receive(null_buffers(), in_flags, receive_handler());
+ int i21 = socket1.async_receive(buffer(mutable_char_buffer), lazy);
+ (void)i21;
+ int i22 = socket1.async_receive(null_buffers(), lazy);
+ (void)i22;
+ int i23 = socket1.async_receive(buffer(mutable_char_buffer),
+ in_flags, lazy);
+ (void)i23;
+ int i24 = socket1.async_receive(null_buffers(), in_flags, lazy);
+ (void)i24;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d21 = socket1.async_receive(buffer(mutable_char_buffer), dlazy);
+ (void)d21;
+ double d22 = socket1.async_receive(null_buffers(), dlazy);
+ (void)d22;
+ double d23 = socket1.async_receive(buffer(mutable_char_buffer),
+ in_flags, dlazy);
+ (void)d23;
+ double d24 = socket1.async_receive(null_buffers(), in_flags, dlazy);
+ (void)d24;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::icmp::endpoint endpoint;
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+ socket1.receive_from(null_buffers(), endpoint);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+ socket1.receive_from(null_buffers(), endpoint, in_flags);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+ socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, receive_handler());
+ socket1.async_receive_from(null_buffers(),
+ endpoint, receive_handler());
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, receive_handler());
+ socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, receive_handler());
+ int i25 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, lazy);
+ (void)i25;
+ int i26 = socket1.async_receive_from(null_buffers(),
+ endpoint, lazy);
+ (void)i26;
+ int i27 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, lazy);
+ (void)i27;
+ int i28 = socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, lazy);
+ (void)i28;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d25 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, dlazy);
+ (void)d25;
+ double d26 = socket1.async_receive_from(null_buffers(),
+ endpoint, dlazy);
+ (void)d26;
+ double d27 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, dlazy);
+ (void)d27;
+ double d28 = socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, dlazy);
+ (void)d28;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_icmp_socket_compile
+
+//------------------------------------------------------------------------------
+
+// ip_icmp_resolver_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::icmp::resolver compile and link correctly. Runtime failures are ignored.
+
+namespace ip_icmp_resolver_compile {
+
+struct resolve_handler
+{
+ resolve_handler() {}
+ void operator()(const asio::error_code&,
+ asio::ip::icmp::resolver::results_type) {}
+#if defined(ASIO_HAS_MOVE)
+ resolve_handler(resolve_handler&&) {}
+private:
+ resolve_handler(const resolve_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::icmp::resolver::query q(ip::icmp::v4(), "localhost", "0");
+#endif // !defined(ASIO_NO_DEPRECATED)
+ ip::icmp::endpoint e(ip::address_v4::loopback(), 0);
+
+ // basic_resolver constructors.
+
+ ip::icmp::resolver resolver(ioc);
+
+#if defined(ASIO_HAS_MOVE)
+ ip::icmp::resolver resolver2(std::move(resolver));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_resolver operators.
+
+#if defined(ASIO_HAS_MOVE)
+ resolver = ip::icmp::resolver(ioc);
+ resolver = std::move(resolver2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = resolver.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::icmp::resolver::executor_type ex = resolver.get_executor();
+ (void)ex;
+
+ // basic_resolver functions.
+
+ resolver.cancel();
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::icmp::resolver::results_type results1 = resolver.resolve(q);
+ (void)results1;
+
+ ip::icmp::resolver::results_type results2 = resolver.resolve(q, ec);
+ (void)results2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::icmp::resolver::results_type results3 = resolver.resolve("", "");
+ (void)results3;
+
+ ip::icmp::resolver::results_type results4 = resolver.resolve("", "", ec);
+ (void)results4;
+
+ ip::icmp::resolver::results_type results5 =
+ resolver.resolve("", "", ip::icmp::resolver::flags());
+ (void)results5;
+
+ ip::icmp::resolver::results_type results6 =
+ resolver.resolve("", "", ip::icmp::resolver::flags(), ec);
+ (void)results6;
+
+ ip::icmp::resolver::results_type results7 =
+ resolver.resolve(ip::icmp::v4(), "", "");
+ (void)results7;
+
+ ip::icmp::resolver::results_type results8 =
+ resolver.resolve(ip::icmp::v4(), "", "", ec);
+ (void)results8;
+
+ ip::icmp::resolver::results_type results9 =
+ resolver.resolve(ip::icmp::v4(), "", "", ip::icmp::resolver::flags());
+ (void)results9;
+
+ ip::icmp::resolver::results_type results10 =
+ resolver.resolve(ip::icmp::v4(), "", "", ip::icmp::resolver::flags(), ec);
+ (void)results10;
+
+ ip::icmp::resolver::results_type results11 = resolver.resolve(e);
+ (void)results11;
+
+ ip::icmp::resolver::results_type results12 = resolver.resolve(e, ec);
+ (void)results12;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ resolver.async_resolve(q, resolve_handler());
+ int i1 = resolver.async_resolve(q, lazy);
+ (void)i1;
+ double d1 = resolver.async_resolve(q, dlazy);
+ (void)d1;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "", resolve_handler());
+ int i2 = resolver.async_resolve("", "", lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d2 = resolver.async_resolve("", "", dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "",
+ ip::icmp::resolver::flags(), resolve_handler());
+ int i3 = resolver.async_resolve("", "",
+ ip::icmp::resolver::flags(), lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = resolver.async_resolve("", "",
+ ip::icmp::resolver::flags(), dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::icmp::v4(), "", "", resolve_handler());
+ int i4 = resolver.async_resolve(ip::icmp::v4(), "", "", lazy);
+ (void)i4;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d4 = resolver.async_resolve(ip::icmp::v4(), "", "", dlazy);
+ (void)d4;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::icmp::v4(),
+ "", "", ip::icmp::resolver::flags(), resolve_handler());
+ int i5 = resolver.async_resolve(ip::icmp::v4(),
+ "", "", ip::icmp::resolver::flags(), lazy);
+ (void)i5;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d5 = resolver.async_resolve(ip::icmp::v4(),
+ "", "", ip::icmp::resolver::flags(), dlazy);
+ (void)d5;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(e, resolve_handler());
+ int i6 = resolver.async_resolve(e, lazy);
+ (void)i6;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d6 = resolver.async_resolve(e, dlazy);
+ (void)d6;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_icmp_resolver_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/icmp",
+ ASIO_TEST_CASE(ip_icmp_socket_compile::test)
+ ASIO_TEST_CASE(ip_icmp_resolver_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/multicast.cpp b/3rdparty/asio/src/tests/unit/ip/multicast.cpp
new file mode 100644
index 00000000000..a3cff0b778b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/multicast.cpp
@@ -0,0 +1,363 @@
+//
+// multicast.cpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/multicast.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/ip/udp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// ip_multicast_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all nested classes, enums and constants in
+// ip::multicast compile and link correctly. Runtime failures are ignored.
+
+namespace ip_multicast_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::udp::socket sock(ioc);
+ const ip::address address;
+ const ip::address_v4 address_v4;
+ const ip::address_v6 address_v6;
+
+ // join_group class.
+
+ ip::multicast::join_group join_group1;
+ ip::multicast::join_group join_group2(address);
+ ip::multicast::join_group join_group3(address_v4);
+ ip::multicast::join_group join_group4(address_v4, address_v4);
+ ip::multicast::join_group join_group5(address_v6);
+ ip::multicast::join_group join_group6(address_v6, 1);
+ sock.set_option(join_group6);
+
+ // leave_group class.
+
+ ip::multicast::leave_group leave_group1;
+ ip::multicast::leave_group leave_group2(address);
+ ip::multicast::leave_group leave_group3(address_v4);
+ ip::multicast::leave_group leave_group4(address_v4, address_v4);
+ ip::multicast::leave_group leave_group5(address_v6);
+ ip::multicast::leave_group leave_group6(address_v6, 1);
+ sock.set_option(leave_group6);
+
+ // outbound_interface class.
+
+ ip::multicast::outbound_interface outbound_interface1;
+ ip::multicast::outbound_interface outbound_interface2(address_v4);
+ ip::multicast::outbound_interface outbound_interface3(1);
+ sock.set_option(outbound_interface3);
+
+ // hops class.
+
+ ip::multicast::hops hops1(1024);
+ sock.set_option(hops1);
+ ip::multicast::hops hops2;
+ sock.get_option(hops2);
+ hops1 = 1;
+ (void)static_cast<int>(hops1.value());
+
+ // enable_loopback class.
+
+ ip::multicast::enable_loopback enable_loopback1(true);
+ sock.set_option(enable_loopback1);
+ ip::multicast::enable_loopback enable_loopback2;
+ sock.get_option(enable_loopback2);
+ enable_loopback1 = true;
+ (void)static_cast<bool>(enable_loopback1);
+ (void)static_cast<bool>(!enable_loopback1);
+ (void)static_cast<bool>(enable_loopback1.value());
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_multicast_compile
+
+//------------------------------------------------------------------------------
+
+// ip_multicast_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the socket options defined
+// in the ip::multicast namespace.
+
+namespace ip_multicast_runtime {
+
+#if defined(__hpux)
+// HP-UX doesn't declare this function extern "C", so it is declared again here
+// to avoid a linker error about an undefined symbol.
+extern "C" unsigned int if_nametoindex(const char*);
+#endif // defined(__hpux)
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+ asio::error_code ec;
+
+ ip::udp::endpoint ep_v4(ip::address_v4::loopback(), 0);
+ ip::udp::socket sock_v4(ioc);
+ sock_v4.open(ep_v4.protocol(), ec);
+ sock_v4.bind(ep_v4, ec);
+ bool have_v4 = !ec;
+
+ ip::udp::endpoint ep_v6(ip::address_v6::loopback(), 0);
+ ip::udp::socket sock_v6(ioc);
+ sock_v6.open(ep_v6.protocol(), ec);
+ sock_v6.bind(ep_v6, ec);
+ bool have_v6 = !ec;
+
+ ASIO_CHECK(have_v4 || have_v6);
+
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Windows CE seems to have problems with some multicast group addresses.
+ // The following address works on CE, but as it is not a private multicast
+ // address it will not be used on other platforms.
+ const ip::address multicast_address_v4 = ip::make_address("239.0.0.4", ec);
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ const ip::address multicast_address_v4 = ip::make_address("239.255.0.1", ec);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!have_v4 || !ec);
+
+#if (defined(__MACH__) && defined(__APPLE__)) \
+ || defined(__FreeBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__OpenBSD__)
+ const ip::address multicast_address_v6 = ip::make_address("ff02::1%lo0", ec);
+#else // (defined(__MACH__) && defined(__APPLE__))
+ // || defined(__FreeBSD__)
+ // || defined(__NetBSD__)
+ // || defined(__OpenBSD__)
+ const ip::address multicast_address_v6 = ip::make_address("ff01::1", ec);
+#endif // (defined(__MACH__) && defined(__APPLE__))
+ // || defined(__FreeBSD__)
+ // || defined(__NetBSD__)
+ // || defined(__OpenBSD__)
+ ASIO_CHECK(!have_v6 || !ec);
+
+ // join_group class.
+
+ if (have_v4)
+ {
+ ip::multicast::join_group join_group(multicast_address_v4);
+ sock_v4.set_option(join_group, ec);
+ ASIO_CHECK_MESSAGE(!ec || ec == error::no_such_device,
+ ec.value() << ", " << ec.message());
+
+ if (!ec)
+ {
+ // leave_group class.
+
+ ip::multicast::leave_group leave_group(multicast_address_v4);
+ sock_v4.set_option(leave_group, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ }
+ }
+
+ if (have_v6)
+ {
+ ip::multicast::join_group join_group(multicast_address_v6);
+ sock_v6.set_option(join_group, ec);
+ ASIO_CHECK_MESSAGE(!ec || ec == error::no_such_device,
+ ec.value() << ", " << ec.message());
+
+ if (!ec)
+ {
+ // leave_group class.
+
+ ip::multicast::leave_group leave_group(multicast_address_v6);
+ sock_v6.set_option(leave_group, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ }
+ }
+
+ // outbound_interface class.
+
+ if (have_v4)
+ {
+ ip::multicast::outbound_interface outbound_interface(
+ ip::address_v4::loopback());
+ sock_v4.set_option(outbound_interface, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ }
+
+ if (have_v6)
+ {
+#if defined(__hpux)
+ ip::multicast::outbound_interface outbound_interface(if_nametoindex("lo0"));
+#else
+ ip::multicast::outbound_interface outbound_interface(1);
+#endif
+ sock_v6.set_option(outbound_interface, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ }
+
+ // hops class.
+
+ if (have_v4)
+ {
+ ip::multicast::hops hops1(1);
+ ASIO_CHECK(hops1.value() == 1);
+ sock_v4.set_option(hops1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::hops hops2;
+ sock_v4.get_option(hops2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(hops2.value() == 1);
+
+ ip::multicast::hops hops3(0);
+ ASIO_CHECK(hops3.value() == 0);
+ sock_v4.set_option(hops3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::hops hops4;
+ sock_v4.get_option(hops4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(hops4.value() == 0);
+ }
+
+ if (have_v6)
+ {
+ ip::multicast::hops hops1(1);
+ ASIO_CHECK(hops1.value() == 1);
+ sock_v6.set_option(hops1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::hops hops2;
+ sock_v6.get_option(hops2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(hops2.value() == 1);
+
+ ip::multicast::hops hops3(0);
+ ASIO_CHECK(hops3.value() == 0);
+ sock_v6.set_option(hops3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::hops hops4;
+ sock_v6.get_option(hops4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(hops4.value() == 0);
+ }
+
+ // enable_loopback class.
+
+ if (have_v4)
+ {
+ ip::multicast::enable_loopback enable_loopback1(true);
+ ASIO_CHECK(enable_loopback1.value());
+ ASIO_CHECK(static_cast<bool>(enable_loopback1));
+ ASIO_CHECK(!!enable_loopback1);
+ sock_v4.set_option(enable_loopback1, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::multicast::enable_loopback enable_loopback2;
+ sock_v4.get_option(enable_loopback2, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Not supported under Windows CE but can get value.
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(enable_loopback2.value());
+ ASIO_CHECK(static_cast<bool>(enable_loopback2));
+ ASIO_CHECK(!!enable_loopback2);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::multicast::enable_loopback enable_loopback3(false);
+ ASIO_CHECK(!enable_loopback3.value());
+ ASIO_CHECK(!static_cast<bool>(enable_loopback3));
+ ASIO_CHECK(!enable_loopback3);
+ sock_v4.set_option(enable_loopback3, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::multicast::enable_loopback enable_loopback4;
+ sock_v4.get_option(enable_loopback4, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Not supported under Windows CE but can get value.
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!enable_loopback4.value());
+ ASIO_CHECK(!static_cast<bool>(enable_loopback4));
+ ASIO_CHECK(!enable_loopback4);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ }
+
+ if (have_v6)
+ {
+ ip::multicast::enable_loopback enable_loopback1(true);
+ ASIO_CHECK(enable_loopback1.value());
+ ASIO_CHECK(static_cast<bool>(enable_loopback1));
+ ASIO_CHECK(!!enable_loopback1);
+ sock_v6.set_option(enable_loopback1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::enable_loopback enable_loopback2;
+ sock_v6.get_option(enable_loopback2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(enable_loopback2.value());
+ ASIO_CHECK(static_cast<bool>(enable_loopback2));
+ ASIO_CHECK(!!enable_loopback2);
+
+ ip::multicast::enable_loopback enable_loopback3(false);
+ ASIO_CHECK(!enable_loopback3.value());
+ ASIO_CHECK(!static_cast<bool>(enable_loopback3));
+ ASIO_CHECK(!enable_loopback3);
+ sock_v6.set_option(enable_loopback3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ ip::multicast::enable_loopback enable_loopback4;
+ sock_v6.get_option(enable_loopback4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!enable_loopback4.value());
+ ASIO_CHECK(!static_cast<bool>(enable_loopback4));
+ ASIO_CHECK(!enable_loopback4);
+ }
+}
+
+} // namespace ip_multicast_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/multicast",
+ ASIO_TEST_CASE(ip_multicast_compile::test)
+ ASIO_TEST_CASE(ip_multicast_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/network_v4.cpp b/3rdparty/asio/src/tests/unit/ip/network_v4.cpp
new file mode 100644
index 00000000000..7d07ffd6928
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/network_v4.cpp
@@ -0,0 +1,301 @@
+//
+// network_v4.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/network_v4.hpp"
+
+#include "../unit_test.hpp"
+#include <sstream>
+
+//------------------------------------------------------------------------------
+
+// ip_network_v4_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::network_v4 compile and link correctly. Runtime failures are ignored.
+
+namespace ip_network_v4_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ // network_v4 constructors.
+
+ ip::network_v4 net1(ip::make_address_v4("192.168.1.0"), 32);
+ ip::network_v4 net2(ip::make_address_v4("192.168.1.0"),
+ ip::make_address_v4("255.255.255.0"));
+
+ // network_v4 functions.
+
+ ip::address_v4 addr1 = net1.address();
+ (void)addr1;
+
+ unsigned short prefix_len = net1.prefix_length();
+ (void)prefix_len;
+
+ ip::address_v4 addr2 = net1.netmask();
+ (void)addr2;
+
+ ip::address_v4 addr3 = net1.network();
+ (void)addr3;
+
+ ip::address_v4 addr4 = net1.broadcast();
+ (void)addr4;
+
+ ip::address_v4_range hosts = net1.hosts();
+ (void)hosts;
+
+ ip::network_v4 net3 = net1.canonical();
+ (void)net3;
+
+ bool b1 = net1.is_host();
+ (void)b1;
+
+ bool b2 = net1.is_subnet_of(net2);
+ (void)b2;
+
+ std::string s1 = net1.to_string();
+ (void)s1;
+
+ std::string s2 = net1.to_string(ec);
+ (void)s2;
+
+ // network_v4 comparisons.
+
+ bool b3 = (net1 == net2);
+ (void)b3;
+
+ bool b4 = (net1 != net2);
+ (void)b4;
+
+ // network_v4 creation functions.
+
+ net1 = ip::make_network_v4(ip::address_v4(), 24);
+ net1 = ip::make_network_v4(ip::address_v4(), ip::address_v4());
+ net1 = ip::make_network_v4("10.0.0.0/8");
+ net1 = ip::make_network_v4("10.0.0.0/8", ec);
+ net1 = ip::make_network_v4(s1);
+ net1 = ip::make_network_v4(s1, ec);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_value("10.0.0.0/8");
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_value("10.0.0.0/8");
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ net1 = ip::make_network_v4(string_view_value);
+ net1 = ip::make_network_v4(string_view_value, ec);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // network_v4 I/O.
+
+ std::ostringstream os;
+ os << net1;
+
+#if !defined(BOOST_NO_STD_WSTREAMBUF)
+ std::wostringstream wos;
+ wos << net1;
+#endif // !defined(BOOST_NO_STD_WSTREAMBUF)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_network_v4_compile
+
+//------------------------------------------------------------------------------
+
+// ip_network_v4_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that the various public member functions meet the
+// necessary postconditions.
+
+namespace ip_network_v4_runtime {
+
+void test()
+{
+ using asio::ip::address_v4;
+ using asio::ip::make_address_v4;
+ using asio::ip::network_v4;
+ using asio::ip::make_network_v4;
+
+ address_v4 addr = make_address_v4("1.2.3.4");
+
+ // calculate prefix length
+
+ network_v4 net1(addr, make_address_v4("255.255.255.0"));
+ ASIO_CHECK(net1.prefix_length() == 24);
+
+ network_v4 net2(addr, make_address_v4("255.255.255.192"));
+ ASIO_CHECK(net2.prefix_length() == 26);
+
+ network_v4 net3(addr, make_address_v4("128.0.0.0"));
+ ASIO_CHECK(net3.prefix_length() == 1);
+
+ std::string msg;
+ try
+ {
+ make_network_v4(addr, make_address_v4("255.255.255.1"));
+ }
+ catch(std::exception& ex)
+ {
+ msg = ex.what();
+ }
+ ASIO_CHECK(msg == std::string("non-contiguous netmask"));
+
+ msg.clear();
+ try
+ {
+ make_network_v4(addr, make_address_v4("0.255.255.0"));
+ }
+ catch(std::exception& ex)
+ {
+ msg = ex.what();
+ }
+ ASIO_CHECK(msg == std::string("non-contiguous netmask"));
+
+ // calculate netmask
+
+ network_v4 net4(addr, 23);
+ ASIO_CHECK(net4.netmask() == make_address_v4("255.255.254.0"));
+
+ network_v4 net5(addr, 12);
+ ASIO_CHECK(net5.netmask() == make_address_v4("255.240.0.0"));
+
+ network_v4 net6(addr, 24);
+ ASIO_CHECK(net6.netmask() == make_address_v4("255.255.255.0"));
+
+ network_v4 net7(addr, 16);
+ ASIO_CHECK(net7.netmask() == make_address_v4("255.255.0.0"));
+
+ network_v4 net8(addr, 8);
+ ASIO_CHECK(net8.netmask() == make_address_v4("255.0.0.0"));
+
+ network_v4 net9(addr, 32);
+ ASIO_CHECK(net9.netmask() == make_address_v4("255.255.255.255"));
+
+ network_v4 net10(addr, 1);
+ ASIO_CHECK(net10.netmask() == make_address_v4("128.0.0.0"));
+
+ network_v4 net11(addr, 0);
+ ASIO_CHECK(net11.netmask() == make_address_v4("0.0.0.0"));
+
+ msg.clear();
+ try
+ {
+ make_network_v4(addr, 33);
+ }
+ catch(std::out_of_range& ex)
+ {
+ msg = ex.what();
+ }
+ ASIO_CHECK(msg == std::string("prefix length too large"));
+
+ // construct address range from address and prefix length
+ ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 32).network() == make_address_v4("192.168.77.100"));
+ ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 24).network() == make_address_v4("192.168.77.0"));
+ ASIO_CHECK(network_v4(make_address_v4("192.168.77.128"), 25).network() == make_address_v4("192.168.77.128"));
+
+ // construct address range from string in CIDR notation
+ ASIO_CHECK(make_network_v4("192.168.77.100/32").network() == make_address_v4("192.168.77.100"));
+ ASIO_CHECK(make_network_v4("192.168.77.100/24").network() == make_address_v4("192.168.77.0"));
+ ASIO_CHECK(make_network_v4("192.168.77.128/25").network() == make_address_v4("192.168.77.128"));
+
+ // prefix length
+ ASIO_CHECK(make_network_v4("193.99.144.80/24").prefix_length() == 24);
+ ASIO_CHECK(network_v4(make_address_v4("193.99.144.80"), 24).prefix_length() == 24);
+ ASIO_CHECK(network_v4(make_address_v4("192.168.77.0"), make_address_v4("255.255.255.0")).prefix_length() == 24);
+
+ // to string
+ std::string a("192.168.77.0/32");
+ ASIO_CHECK(make_network_v4(a.c_str()).to_string() == a);
+ ASIO_CHECK(network_v4(make_address_v4("192.168.77.10"), 24).to_string() == std::string("192.168.77.10/24"));
+
+ // return host part
+ ASIO_CHECK(make_network_v4("192.168.77.11/24").address() == make_address_v4("192.168.77.11"));
+
+ // return host in CIDR notation
+ ASIO_CHECK(make_network_v4("192.168.78.30/20").address().to_string() == "192.168.78.30");
+
+ // return network in CIDR notation
+ ASIO_CHECK(make_network_v4("192.168.78.30/20").canonical().to_string() == "192.168.64.0/20");
+
+ // is host
+ ASIO_CHECK(make_network_v4("192.168.77.0/32").is_host());
+ ASIO_CHECK(!make_network_v4("192.168.77.0/31").is_host());
+
+ // is real subnet of
+ ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.0.0/16")));
+ ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.192.168/16")));
+ ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.192.168/16")));
+ ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/16")));
+ ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/23")));
+ ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/0")));
+ ASIO_CHECK(make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/24")));
+
+ ASIO_CHECK(!make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/32")));
+ ASIO_CHECK(!make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.1.0/24")));
+ ASIO_CHECK(!make_network_v4("192.168.0.0/16").is_subnet_of(make_network_v4("192.168.1.0/24")));
+
+ network_v4 r(make_network_v4("192.168.0.0/24"));
+ ASIO_CHECK(!r.is_subnet_of(r));
+
+ network_v4 net12(make_network_v4("192.168.0.2/24"));
+ network_v4 net13(make_network_v4("192.168.1.1/28"));
+ network_v4 net14(make_network_v4("192.168.1.21/28"));
+ // network
+ ASIO_CHECK(net12.network() == make_address_v4("192.168.0.0"));
+ ASIO_CHECK(net13.network() == make_address_v4("192.168.1.0"));
+ ASIO_CHECK(net14.network() == make_address_v4("192.168.1.16"));
+ // netmask
+ ASIO_CHECK(net12.netmask() == make_address_v4("255.255.255.0"));
+ ASIO_CHECK(net13.netmask() == make_address_v4("255.255.255.240"));
+ ASIO_CHECK(net14.netmask() == make_address_v4("255.255.255.240"));
+ // broadcast
+ ASIO_CHECK(net12.broadcast() == make_address_v4("192.168.0.255"));
+ ASIO_CHECK(net13.broadcast() == make_address_v4("192.168.1.15"));
+ ASIO_CHECK(net14.broadcast() == make_address_v4("192.168.1.31"));
+ // iterator
+ ASIO_CHECK(std::distance(net12.hosts().begin(),net12.hosts().end()) == 254);
+ ASIO_CHECK(*net12.hosts().begin() == make_address_v4("192.168.0.1"));
+ ASIO_CHECK(net12.hosts().end() != net12.hosts().find(make_address_v4("192.168.0.10")));
+ ASIO_CHECK(net12.hosts().end() == net12.hosts().find(make_address_v4("192.168.1.10")));
+ ASIO_CHECK(std::distance(net13.hosts().begin(),net13.hosts().end()) == 14);
+ ASIO_CHECK(*net13.hosts().begin() == make_address_v4("192.168.1.1"));
+ ASIO_CHECK(net13.hosts().end() != net13.hosts().find(make_address_v4("192.168.1.14")));
+ ASIO_CHECK(net13.hosts().end() == net13.hosts().find(make_address_v4("192.168.1.15")));
+ ASIO_CHECK(std::distance(net14.hosts().begin(),net14.hosts().end()) == 14);
+ ASIO_CHECK(*net14.hosts().begin() == make_address_v4("192.168.1.17"));
+ ASIO_CHECK(net14.hosts().end() != net14.hosts().find(make_address_v4("192.168.1.30")));
+ ASIO_CHECK(net14.hosts().end() == net14.hosts().find(make_address_v4("192.168.1.31")));
+}
+
+} // namespace ip_network_v4_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/network_v4",
+ ASIO_TEST_CASE(ip_network_v4_compile::test)
+ ASIO_TEST_CASE(ip_network_v4_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/network_v6.cpp b/3rdparty/asio/src/tests/unit/ip/network_v6.cpp
new file mode 100644
index 00000000000..c7e458f08f1
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/network_v6.cpp
@@ -0,0 +1,225 @@
+//
+// network_v6.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/network_v6.hpp"
+
+#include "../unit_test.hpp"
+#include <sstream>
+
+//------------------------------------------------------------------------------
+
+// ip_network_v6_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::network_v6 compile and link correctly. Runtime failures are ignored.
+
+namespace ip_network_v6_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ asio::error_code ec;
+
+ // network_v6 constructors.
+
+ ip::network_v6 net1(ip::make_address_v6("2001:370::10:7344"), 64);
+ ip::network_v6 net2(ip::make_address_v6("2001:370::10:7345"), 96);
+
+ // network_v6 functions.
+
+ ip::address_v6 addr1 = net1.address();
+ (void)addr1;
+
+ unsigned short prefix_len = net1.prefix_length();
+ (void)prefix_len;
+
+ ip::address_v6 addr3 = net1.network();
+ (void)addr3;
+
+ ip::address_v6_range hosts = net1.hosts();
+ (void)hosts;
+
+ ip::network_v6 net3 = net1.canonical();
+ (void)net3;
+
+ bool b1 = net1.is_host();
+ (void)b1;
+
+ bool b2 = net1.is_subnet_of(net2);
+ (void)b2;
+
+ std::string s1 = net1.to_string();
+ (void)s1;
+
+ std::string s2 = net1.to_string(ec);
+ (void)s2;
+
+ // network_v6 comparisons.
+
+ bool b3 = (net1 == net2);
+ (void)b3;
+
+ bool b4 = (net1 != net2);
+ (void)b4;
+
+ // network_v6 creation functions.
+
+ net1 = ip::make_network_v6(ip::address_v6(), 24);
+ net1 = ip::make_network_v6("10.0.0.0/8");
+ net1 = ip::make_network_v6("10.0.0.0/8", ec);
+ net1 = ip::make_network_v6(s1);
+ net1 = ip::make_network_v6(s1, ec);
+#if defined(ASIO_HAS_STD_STRING_VIEW)
+# if defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::experimental::string_view string_view_value("0::0/8");
+# else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ std::string_view string_view_value("0::0/8");
+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+ net1 = ip::make_network_v6(string_view_value);
+ net1 = ip::make_network_v6(string_view_value, ec);
+#endif // defined(ASIO_HAS_STD_STRING_VIEW)
+
+ // network_v6 I/O.
+
+ std::ostringstream os;
+ os << net1;
+
+#if !defined(BOOST_NO_STD_WSTREAMBUF)
+ std::wostringstream wos;
+ wos << net1;
+#endif // !defined(BOOST_NO_STD_WSTREAMBUF)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_network_v6_compile
+
+//------------------------------------------------------------------------------
+
+// ip_network_v6_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that the various public member functions meet the
+// necessary postconditions.
+
+namespace ip_network_v6_runtime {
+
+void test()
+{
+ using asio::ip::address_v6;
+ using asio::ip::make_address_v6;
+ using asio::ip::network_v6;
+ using asio::ip::make_network_v6;
+
+ address_v6 addr = make_address_v6("2001:370::10:7344");
+
+ std::string msg;
+ try
+ {
+ make_network_v6(addr, 129);
+ }
+ catch(std::out_of_range& ex)
+ {
+ msg = ex.what();
+ }
+ ASIO_CHECK(msg == std::string("prefix length too large"));
+
+ // construct address range from address and prefix length
+ ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 128).network() == make_address_v6("2001:370::10:7344"));
+ ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 64).network() == make_address_v6("2001:370::"));
+ ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).network() == make_address_v6("2001:360::"));
+
+ // construct address range from string in CIDR notation
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/128").network() == make_address_v6("2001:370::10:7344"));
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/64").network() == make_address_v6("2001:370::"));
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/27").network() == make_address_v6("2001:360::"));
+
+ // prefix length
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/128").prefix_length() == 128);
+ ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).prefix_length() == 27);
+
+ // to string
+ std::string a("2001:370::10:7344/64");
+ ASIO_CHECK(make_network_v6(a.c_str()).to_string() == a);
+ ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).to_string() == std::string("2001:370::10:7344/27"));
+
+ // return host part
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/64").address() == make_address_v6("2001:370::10:7344"));
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/27").address().to_string() == "2001:370::10:7344");
+
+ // return network in CIDR notation
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/27").canonical().to_string() == "2001:360::/27");
+
+ // is host
+ ASIO_CHECK(make_network_v6("2001:370::10:7344/128").is_host());
+ ASIO_CHECK(!make_network_v6("2001:370::10:7344/127").is_host());
+
+ // is real subnet of
+ ASIO_CHECK(make_network_v6("2001:370::10:3744/64").is_subnet_of(make_network_v6("2001:370::/16")));
+ ASIO_CHECK(make_network_v6("2001:370::/64").is_subnet_of(make_network_v6("2001:370::/16")));
+ ASIO_CHECK(make_network_v6("2001:0db8:85a3::/64").is_subnet_of(make_network_v6("2001:0d00::/24")));
+
+ ASIO_CHECK(!make_network_v6("2001:370::10:3744/128").is_subnet_of(make_network_v6("2001:370::10:3744/128")));
+ ASIO_CHECK(make_network_v6("2001:0db8:85a3::/64").is_subnet_of(make_network_v6("2001:0dc0::/24")));
+
+ network_v6 r(make_network_v6("2001:370::/64"));
+ ASIO_CHECK(!r.is_subnet_of(r));
+
+ network_v6 net12(make_network_v6("2001:370::10:7344/64"));
+ network_v6 net13(make_network_v6("2001:0db8::/127"));
+ network_v6 net14(make_network_v6("2001:0db8::/125"));
+ network_v6 net15(make_network_v6("2001:0db8::/119"));
+
+ // network
+ ASIO_CHECK(net12.network() == make_address_v6("2001:370::"));
+ ASIO_CHECK(net13.network() == make_address_v6("2001:0db8::"));
+ ASIO_CHECK(net14.network() == make_address_v6("2001:0db8::"));
+ ASIO_CHECK(net15.network() == make_address_v6("2001:0db8::"));
+
+ // iterator
+ //ASIO_CHECK(std::distance(net12.hosts().begin(),net12.hosts().end()) == 18446744073709552000);
+ ASIO_CHECK(std::distance(net13.hosts().begin(),net13.hosts().end()) == 2);
+ ASIO_CHECK(std::distance(net14.hosts().begin(),net14.hosts().end()) == 8);
+ ASIO_CHECK(std::distance(net15.hosts().begin(),net15.hosts().end()) == 512);
+ ASIO_CHECK(*net12.hosts().begin() == make_address_v6("2001:0370::"));
+ ASIO_CHECK(net12.hosts().end() != net12.hosts().find(make_address_v6("2001:0370::ffff:ffff:ffff:ffff")));
+ ASIO_CHECK(*net13.hosts().begin() == make_address_v6("2001:0db8::"));
+ ASIO_CHECK(net13.hosts().end() != net13.hosts().find(make_address_v6("2001:0db8::1")));
+ ASIO_CHECK(net13.hosts().end() == net13.hosts().find(make_address_v6("2001:0db8::2")));
+ ASIO_CHECK(*net14.hosts().begin() == make_address_v6("2001:0db8::"));
+ ASIO_CHECK(net14.hosts().end() != net14.hosts().find(make_address_v6("2001:0db8::7")));
+ ASIO_CHECK(net14.hosts().end() == net14.hosts().find(make_address_v6("2001:0db8::8")));
+ ASIO_CHECK(*net15.hosts().begin() == make_address_v6("2001:0db8::"));
+ ASIO_CHECK(net15.hosts().end() != net15.hosts().find(make_address_v6("2001:0db8::01ff")));
+ ASIO_CHECK(net15.hosts().end() == net15.hosts().find(make_address_v6("2001:0db8::0200")));
+}
+
+} // namespace ip_network_v6_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/network_v6",
+ ASIO_TEST_CASE(ip_network_v6_compile::test)
+ ASIO_TEST_CASE(ip_network_v6_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/resolver_query_base.cpp b/3rdparty/asio/src/tests/unit/ip/resolver_query_base.cpp
new file mode 100644
index 00000000000..d9bbd325583
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/resolver_query_base.cpp
@@ -0,0 +1,25 @@
+//
+// resolver_query_base.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/resolver_query_base.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/resolver_query_base",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/resolver_service.cpp b/3rdparty/asio/src/tests/unit/ip/resolver_service.cpp
new file mode 100644
index 00000000000..7b0ac2a9ac3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/resolver_service.cpp
@@ -0,0 +1,25 @@
+//
+// resolver_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/resolver_service.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ip/resolver_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/tcp.cpp b/3rdparty/asio/src/tests/unit/ip/tcp.cpp
new file mode 100644
index 00000000000..22cee2aa042
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/tcp.cpp
@@ -0,0 +1,1372 @@
+//
+// tcp.cpp
+// ~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Enable cancel() support on Windows.
+#define ASIO_ENABLE_CANCELIO 1
+
+// Test that header file is self-contained.
+#include "asio/ip/tcp.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "asio/read.hpp"
+#include "asio/write.hpp"
+#include "../unit_test.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../archetypes/deprecated_async_result.hpp"
+#include "../archetypes/gettable_socket_option.hpp"
+#include "../archetypes/io_control_command.hpp"
+#include "../archetypes/settable_socket_option.hpp"
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+# include <boost/array.hpp>
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_compile test
+// ~~~~~~~~~~~~~~~~~~~
+// The following test checks that all nested classes, enums and constants in
+// ip::tcp compile and link correctly. Runtime failures are ignored.
+
+namespace ip_tcp_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::tcp::socket sock(ioc);
+
+ // no_delay class.
+
+ ip::tcp::no_delay no_delay1(true);
+ sock.set_option(no_delay1);
+ ip::tcp::no_delay no_delay2;
+ sock.get_option(no_delay2);
+ no_delay1 = true;
+ (void)static_cast<bool>(no_delay1);
+ (void)static_cast<bool>(!no_delay1);
+ (void)static_cast<bool>(no_delay1.value());
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_compile
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_runtime test
+// ~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::tcp class.
+
+namespace ip_tcp_runtime {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+ ip::tcp::socket sock(ioc, ip::tcp::v4());
+ asio::error_code ec;
+
+ // no_delay class.
+
+ ip::tcp::no_delay no_delay1(true);
+ ASIO_CHECK(no_delay1.value());
+ ASIO_CHECK(static_cast<bool>(no_delay1));
+ ASIO_CHECK(!!no_delay1);
+ sock.set_option(no_delay1, ec);
+ ASIO_CHECK(!ec);
+
+ ip::tcp::no_delay no_delay2;
+ sock.get_option(no_delay2, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(no_delay2.value());
+ ASIO_CHECK(static_cast<bool>(no_delay2));
+ ASIO_CHECK(!!no_delay2);
+
+ ip::tcp::no_delay no_delay3(false);
+ ASIO_CHECK(!no_delay3.value());
+ ASIO_CHECK(!static_cast<bool>(no_delay3));
+ ASIO_CHECK(!no_delay3);
+ sock.set_option(no_delay3, ec);
+ ASIO_CHECK(!ec);
+
+ ip::tcp::no_delay no_delay4;
+ sock.get_option(no_delay4, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(!no_delay4.value());
+ ASIO_CHECK(!static_cast<bool>(no_delay4));
+ ASIO_CHECK(!no_delay4);
+}
+
+} // namespace ip_tcp_runtime
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::tcp::socket compile and link correctly. Runtime failures are ignored.
+
+namespace ip_tcp_socket_compile {
+
+struct connect_handler
+{
+ connect_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ connect_handler(connect_handler&&) {}
+private:
+ connect_handler(const connect_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct wait_handler
+{
+ wait_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ wait_handler(wait_handler&&) {}
+private:
+ wait_handler(const wait_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct send_handler
+{
+ send_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ send_handler(send_handler&&) {}
+private:
+ send_handler(const send_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct receive_handler
+{
+ receive_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ receive_handler(receive_handler&&) {}
+private:
+ receive_handler(const receive_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct write_some_handler
+{
+ write_some_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ write_some_handler(write_some_handler&&) {}
+private:
+ write_some_handler(const write_some_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct read_some_handler
+{
+ read_some_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ read_some_handler(read_some_handler&&) {}
+private:
+ read_some_handler(const read_some_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ using boost::array;
+#else // defined(ASIO_HAS_BOOST_ARRAY)
+ using std::array;
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ array<asio::mutable_buffer, 2> mutable_buffers = {{
+ asio::buffer(mutable_char_buffer, 10),
+ asio::buffer(mutable_char_buffer + 10, 10) }};
+ array<asio::const_buffer, 2> const_buffers = {{
+ asio::buffer(const_char_buffer, 10),
+ asio::buffer(const_char_buffer + 10, 10) }};
+ socket_base::message_flags in_flags = 0;
+ archetypes::settable_socket_option<void> settable_socket_option1;
+ archetypes::settable_socket_option<int> settable_socket_option2;
+ archetypes::settable_socket_option<double> settable_socket_option3;
+ archetypes::gettable_socket_option<void> gettable_socket_option1;
+ archetypes::gettable_socket_option<int> gettable_socket_option2;
+ archetypes::gettable_socket_option<double> gettable_socket_option3;
+ archetypes::io_control_command io_control_command;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+
+ // basic_stream_socket constructors.
+
+ ip::tcp::socket socket1(ioc);
+ ip::tcp::socket socket2(ioc, ip::tcp::v4());
+ ip::tcp::socket socket3(ioc, ip::tcp::v6());
+ ip::tcp::socket socket4(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0));
+ ip::tcp::socket socket5(ioc, ip::tcp::endpoint(ip::tcp::v6(), 0));
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::tcp::socket::native_handle_type native_socket1
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ ip::tcp::socket socket6(ioc, ip::tcp::v4(), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ ip::tcp::socket socket7(std::move(socket5));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_stream_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = ip::tcp::socket(ioc);
+ socket1 = std::move(socket2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::tcp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+ // basic_socket functions.
+
+ ip::tcp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ const ip::tcp::socket& socket8 = socket1;
+ const ip::tcp::socket::lowest_layer_type& lowest_layer2
+ = socket8.lowest_layer();
+ (void)lowest_layer2;
+
+ socket1.open(ip::tcp::v4());
+ socket1.open(ip::tcp::v6());
+ socket1.open(ip::tcp::v4(), ec);
+ socket1.open(ip::tcp::v6(), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::tcp::socket::native_handle_type native_socket2
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ socket1.assign(ip::tcp::v4(), native_socket2);
+ ip::tcp::socket::native_handle_type native_socket3
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ socket1.assign(ip::tcp::v4(), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ ip::tcp::socket::native_handle_type native_socket4
+ = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0));
+ socket1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0));
+ socket1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
+ socket1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
+
+ socket1.connect(ip::tcp::endpoint(ip::tcp::v4(), 0));
+ socket1.connect(ip::tcp::endpoint(ip::tcp::v6(), 0));
+ socket1.connect(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
+ socket1.connect(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
+
+ socket1.async_connect(ip::tcp::endpoint(ip::tcp::v4(), 0),
+ connect_handler());
+ socket1.async_connect(ip::tcp::endpoint(ip::tcp::v6(), 0),
+ connect_handler());
+ int i1 = socket1.async_connect(ip::tcp::endpoint(ip::tcp::v4(), 0), lazy);
+ (void)i1;
+ int i2 = socket1.async_connect(ip::tcp::endpoint(ip::tcp::v6(), 0), lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d1 = socket1.async_connect(
+ ip::tcp::endpoint(ip::tcp::v4(), 0), dlazy);
+ (void)d1;
+ double d2 = socket1.async_connect(
+ ip::tcp::endpoint(ip::tcp::v6(), 0), dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.set_option(settable_socket_option1);
+ socket1.set_option(settable_socket_option1, ec);
+ socket1.set_option(settable_socket_option2);
+ socket1.set_option(settable_socket_option2, ec);
+ socket1.set_option(settable_socket_option3);
+ socket1.set_option(settable_socket_option3, ec);
+
+ socket1.get_option(gettable_socket_option1);
+ socket1.get_option(gettable_socket_option1, ec);
+ socket1.get_option(gettable_socket_option2);
+ socket1.get_option(gettable_socket_option2, ec);
+ socket1.get_option(gettable_socket_option3);
+ socket1.get_option(gettable_socket_option3, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ bool non_blocking1 = socket1.non_blocking();
+ (void)non_blocking1;
+ socket1.non_blocking(true);
+ socket1.non_blocking(false, ec);
+
+ bool non_blocking2 = socket1.native_non_blocking();
+ (void)non_blocking2;
+ socket1.native_non_blocking(true);
+ socket1.native_non_blocking(false, ec);
+
+ ip::tcp::endpoint endpoint1 = socket1.local_endpoint();
+ ip::tcp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ ip::tcp::endpoint endpoint3 = socket1.remote_endpoint();
+ ip::tcp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ socket1.wait(socket_base::wait_read);
+ socket1.wait(socket_base::wait_write, ec);
+
+ socket1.async_wait(socket_base::wait_read, wait_handler());
+ int i3 = socket1.async_wait(socket_base::wait_write, lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = socket1.async_wait(socket_base::wait_write, dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_stream_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(mutable_buffers);
+ socket1.send(const_buffers);
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(mutable_buffers, in_flags);
+ socket1.send(const_buffers, in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(mutable_buffers, in_flags, ec);
+ socket1.send(const_buffers, in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler());
+ socket1.async_send(buffer(const_char_buffer), send_handler());
+ socket1.async_send(mutable_buffers, send_handler());
+ socket1.async_send(const_buffers, send_handler());
+ socket1.async_send(null_buffers(), send_handler());
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler());
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler());
+ socket1.async_send(mutable_buffers, in_flags, send_handler());
+ socket1.async_send(const_buffers, in_flags, send_handler());
+ socket1.async_send(null_buffers(), in_flags, send_handler());
+ int i4 = socket1.async_send(buffer(mutable_char_buffer), lazy);
+ (void)i4;
+ int i5 = socket1.async_send(buffer(const_char_buffer), lazy);
+ (void)i5;
+ int i6 = socket1.async_send(mutable_buffers, lazy);
+ (void)i6;
+ int i7 = socket1.async_send(const_buffers, lazy);
+ (void)i7;
+ int i8 = socket1.async_send(null_buffers(), lazy);
+ (void)i8;
+ int i9 = socket1.async_send(buffer(mutable_char_buffer), in_flags, lazy);
+ (void)i9;
+ int i10 = socket1.async_send(buffer(const_char_buffer), in_flags, lazy);
+ (void)i10;
+ int i11 = socket1.async_send(mutable_buffers, in_flags, lazy);
+ (void)i11;
+ int i12 = socket1.async_send(const_buffers, in_flags, lazy);
+ (void)i12;
+ int i13 = socket1.async_send(null_buffers(), in_flags, lazy);
+ (void)i13;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d4 = socket1.async_send(buffer(mutable_char_buffer), dlazy);
+ (void)d4;
+ double d5 = socket1.async_send(buffer(const_char_buffer), dlazy);
+ (void)d5;
+ double d6 = socket1.async_send(mutable_buffers, dlazy);
+ (void)d6;
+ double d7 = socket1.async_send(const_buffers, dlazy);
+ (void)d7;
+ double d8 = socket1.async_send(null_buffers(), dlazy);
+ (void)d8;
+ double d9 = socket1.async_send(
+ buffer(mutable_char_buffer), in_flags, dlazy);
+ (void)d9;
+ double d10 = socket1.async_send(buffer(const_char_buffer), in_flags, dlazy);
+ (void)d10;
+ double d11 = socket1.async_send(mutable_buffers, in_flags, dlazy);
+ (void)d11;
+ double d12 = socket1.async_send(const_buffers, in_flags, dlazy);
+ (void)d12;
+ double d13 = socket1.async_send(null_buffers(), in_flags, dlazy);
+ (void)d13;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(mutable_buffers);
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(mutable_buffers, in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(mutable_buffers, in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler());
+ socket1.async_receive(mutable_buffers, receive_handler());
+ socket1.async_receive(null_buffers(), receive_handler());
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler());
+ socket1.async_receive(mutable_buffers, in_flags, receive_handler());
+ socket1.async_receive(null_buffers(), in_flags, receive_handler());
+ int i14 = socket1.async_receive(buffer(mutable_char_buffer), lazy);
+ (void)i14;
+ int i15 = socket1.async_receive(mutable_buffers, lazy);
+ (void)i15;
+ int i16 = socket1.async_receive(null_buffers(), lazy);
+ (void)i16;
+ int i17 = socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ lazy);
+ (void)i17;
+ int i18 = socket1.async_receive(mutable_buffers, in_flags, lazy);
+ (void)i18;
+ int i19 = socket1.async_receive(null_buffers(), in_flags, lazy);
+ (void)i19;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d14 = socket1.async_receive(buffer(mutable_char_buffer), dlazy);
+ (void)d14;
+ double d15 = socket1.async_receive(mutable_buffers, dlazy);
+ (void)d15;
+ double d16 = socket1.async_receive(null_buffers(), dlazy);
+ (void)d16;
+ double d17 = socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ dlazy);
+ (void)d17;
+ double d18 = socket1.async_receive(mutable_buffers, in_flags, dlazy);
+ (void)d18;
+ double d19 = socket1.async_receive(null_buffers(), in_flags, dlazy);
+ (void)d19;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.write_some(buffer(mutable_char_buffer));
+ socket1.write_some(buffer(const_char_buffer));
+ socket1.write_some(mutable_buffers);
+ socket1.write_some(const_buffers);
+ socket1.write_some(null_buffers());
+ socket1.write_some(buffer(mutable_char_buffer), ec);
+ socket1.write_some(buffer(const_char_buffer), ec);
+ socket1.write_some(mutable_buffers, ec);
+ socket1.write_some(const_buffers, ec);
+ socket1.write_some(null_buffers(), ec);
+
+ socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler());
+ socket1.async_write_some(buffer(const_char_buffer), write_some_handler());
+ socket1.async_write_some(mutable_buffers, write_some_handler());
+ socket1.async_write_some(const_buffers, write_some_handler());
+ socket1.async_write_some(null_buffers(), write_some_handler());
+ int i20 = socket1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i20;
+ int i21 = socket1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i21;
+ int i22 = socket1.async_write_some(mutable_buffers, lazy);
+ (void)i22;
+ int i23 = socket1.async_write_some(const_buffers, lazy);
+ (void)i23;
+ int i24 = socket1.async_write_some(null_buffers(), lazy);
+ (void)i24;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d20 = socket1.async_write_some(buffer(mutable_char_buffer), dlazy);
+ (void)d20;
+ double d21 = socket1.async_write_some(buffer(const_char_buffer), dlazy);
+ (void)d21;
+ double d22 = socket1.async_write_some(mutable_buffers, dlazy);
+ (void)d22;
+ double d23 = socket1.async_write_some(const_buffers, dlazy);
+ (void)d23;
+ double d24 = socket1.async_write_some(null_buffers(), dlazy);
+ (void)d24;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.read_some(buffer(mutable_char_buffer));
+ socket1.read_some(mutable_buffers);
+ socket1.read_some(null_buffers());
+ socket1.read_some(buffer(mutable_char_buffer), ec);
+ socket1.read_some(mutable_buffers, ec);
+ socket1.read_some(null_buffers(), ec);
+
+ socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler());
+ socket1.async_read_some(mutable_buffers, read_some_handler());
+ socket1.async_read_some(null_buffers(), read_some_handler());
+ int i25 = socket1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i25;
+ int i26 = socket1.async_read_some(mutable_buffers, lazy);
+ (void)i26;
+ int i27 = socket1.async_read_some(null_buffers(), lazy);
+ (void)i27;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d25 = socket1.async_read_some(buffer(mutable_char_buffer), dlazy);
+ (void)d25;
+ double d26 = socket1.async_read_some(mutable_buffers, dlazy);
+ (void)d26;
+ double d27 = socket1.async_read_some(null_buffers(), dlazy);
+ (void)d27;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_socket_compile
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_socket_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::tcp::socket class.
+
+namespace ip_tcp_socket_runtime {
+
+static const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void handle_read_noop(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!err);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void handle_write_noop(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!err);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void handle_read(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!err);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+}
+
+void handle_write(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!err);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+}
+
+void handle_read_cancel(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(err == asio::error::operation_aborted);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void handle_read_eof(const asio::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(err == asio::error::eof);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test()
+{
+ using namespace std; // For memcmp.
+ using namespace asio;
+ namespace ip = asio::ip;
+
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ io_context ioc;
+
+ ip::tcp::acceptor acceptor(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0));
+ ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(ip::address_v4::loopback());
+
+ ip::tcp::socket client_side_socket(ioc);
+ ip::tcp::socket server_side_socket(ioc);
+
+ client_side_socket.connect(server_endpoint);
+ acceptor.accept(server_side_socket);
+
+ // No-op read.
+
+ bool read_noop_completed = false;
+ client_side_socket.async_read_some(
+ asio::mutable_buffer(0, 0),
+ bindns::bind(handle_read_noop,
+ _1, _2, &read_noop_completed));
+
+ ioc.run();
+ ASIO_CHECK(read_noop_completed);
+
+ // No-op write.
+
+ bool write_noop_completed = false;
+ client_side_socket.async_write_some(
+ asio::const_buffer(0, 0),
+ bindns::bind(handle_write_noop,
+ _1, _2, &write_noop_completed));
+
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(write_noop_completed);
+
+ // Read and write to transfer data.
+
+ char read_buffer[sizeof(write_data)];
+ bool read_completed = false;
+ asio::async_read(client_side_socket,
+ asio::buffer(read_buffer),
+ bindns::bind(handle_read,
+ _1, _2, &read_completed));
+
+ bool write_completed = false;
+ asio::async_write(server_side_socket,
+ asio::buffer(write_data),
+ bindns::bind(handle_write,
+ _1, _2, &write_completed));
+
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(read_completed);
+ ASIO_CHECK(write_completed);
+ ASIO_CHECK(memcmp(read_buffer, write_data, sizeof(write_data)) == 0);
+
+ // Cancelled read.
+
+ bool read_cancel_completed = false;
+ asio::async_read(server_side_socket,
+ asio::buffer(read_buffer),
+ bindns::bind(handle_read_cancel,
+ _1, _2, &read_cancel_completed));
+
+ ioc.restart();
+ ioc.poll();
+ ASIO_CHECK(!read_cancel_completed);
+
+ server_side_socket.cancel();
+
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(read_cancel_completed);
+
+ // A read when the peer closes socket should fail with eof.
+
+ bool read_eof_completed = false;
+ asio::async_read(client_side_socket,
+ asio::buffer(read_buffer),
+ bindns::bind(handle_read_eof,
+ _1, _2, &read_eof_completed));
+
+ server_side_socket.close();
+
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(read_eof_completed);
+}
+
+} // namespace ip_tcp_socket_runtime
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_acceptor_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::tcp::acceptor compile and link correctly. Runtime failures are ignored.
+
+namespace ip_tcp_acceptor_compile {
+
+struct wait_handler
+{
+ wait_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ wait_handler(wait_handler&&) {}
+private:
+ wait_handler(const wait_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct accept_handler
+{
+ accept_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ accept_handler(accept_handler&&) {}
+private:
+ accept_handler(const accept_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+#if defined(ASIO_HAS_MOVE)
+struct move_accept_handler
+{
+ move_accept_handler() {}
+ void operator()(
+ const asio::error_code&, asio::ip::tcp::socket) {}
+ move_accept_handler(move_accept_handler&&) {}
+private:
+ move_accept_handler(const move_accept_handler&) {}
+};
+#endif // defined(ASIO_HAS_MOVE)
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::tcp::socket peer_socket(ioc);
+ ip::tcp::endpoint peer_endpoint;
+ archetypes::settable_socket_option<void> settable_socket_option1;
+ archetypes::settable_socket_option<int> settable_socket_option2;
+ archetypes::settable_socket_option<double> settable_socket_option3;
+ archetypes::gettable_socket_option<void> gettable_socket_option1;
+ archetypes::gettable_socket_option<int> gettable_socket_option2;
+ archetypes::gettable_socket_option<double> gettable_socket_option3;
+ archetypes::io_control_command io_control_command;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+
+ // basic_socket_acceptor constructors.
+
+ ip::tcp::acceptor acceptor1(ioc);
+ ip::tcp::acceptor acceptor2(ioc, ip::tcp::v4());
+ ip::tcp::acceptor acceptor3(ioc, ip::tcp::v6());
+ ip::tcp::acceptor acceptor4(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0));
+ ip::tcp::acceptor acceptor5(ioc, ip::tcp::endpoint(ip::tcp::v6(), 0));
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::tcp::acceptor::native_handle_type native_acceptor1
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ ip::tcp::acceptor acceptor6(ioc, ip::tcp::v4(), native_acceptor1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ ip::tcp::acceptor acceptor7(std::move(acceptor5));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_socket_acceptor operators.
+
+#if defined(ASIO_HAS_MOVE)
+ acceptor1 = ip::tcp::acceptor(ioc);
+ acceptor1 = std::move(acceptor2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = acceptor1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::tcp::acceptor::executor_type ex = acceptor1.get_executor();
+ (void)ex;
+
+ // basic_socket_acceptor functions.
+
+ acceptor1.open(ip::tcp::v4());
+ acceptor1.open(ip::tcp::v6());
+ acceptor1.open(ip::tcp::v4(), ec);
+ acceptor1.open(ip::tcp::v6(), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::tcp::acceptor::native_handle_type native_acceptor2
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ acceptor1.assign(ip::tcp::v4(), native_acceptor2);
+ ip::tcp::acceptor::native_handle_type native_acceptor3
+ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ acceptor1.assign(ip::tcp::v4(), native_acceptor3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = acceptor1.is_open();
+ (void)is_open;
+
+ acceptor1.close();
+ acceptor1.close(ec);
+
+ ip::tcp::acceptor::native_handle_type native_acceptor4
+ = acceptor1.native_handle();
+ (void)native_acceptor4;
+
+ acceptor1.cancel();
+ acceptor1.cancel(ec);
+
+ acceptor1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0));
+ acceptor1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0));
+ acceptor1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
+ acceptor1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
+
+ acceptor1.set_option(settable_socket_option1);
+ acceptor1.set_option(settable_socket_option1, ec);
+ acceptor1.set_option(settable_socket_option2);
+ acceptor1.set_option(settable_socket_option2, ec);
+ acceptor1.set_option(settable_socket_option3);
+ acceptor1.set_option(settable_socket_option3, ec);
+
+ acceptor1.get_option(gettable_socket_option1);
+ acceptor1.get_option(gettable_socket_option1, ec);
+ acceptor1.get_option(gettable_socket_option2);
+ acceptor1.get_option(gettable_socket_option2, ec);
+ acceptor1.get_option(gettable_socket_option3);
+ acceptor1.get_option(gettable_socket_option3, ec);
+
+ acceptor1.io_control(io_control_command);
+ acceptor1.io_control(io_control_command, ec);
+
+ bool non_blocking1 = acceptor1.non_blocking();
+ (void)non_blocking1;
+ acceptor1.non_blocking(true);
+ acceptor1.non_blocking(false, ec);
+
+ bool non_blocking2 = acceptor1.native_non_blocking();
+ (void)non_blocking2;
+ acceptor1.native_non_blocking(true);
+ acceptor1.native_non_blocking(false, ec);
+
+ ip::tcp::endpoint endpoint1 = acceptor1.local_endpoint();
+ ip::tcp::endpoint endpoint2 = acceptor1.local_endpoint(ec);
+
+ acceptor1.wait(socket_base::wait_read);
+ acceptor1.wait(socket_base::wait_write, ec);
+
+ acceptor1.async_wait(socket_base::wait_read, wait_handler());
+ int i1 = acceptor1.async_wait(socket_base::wait_write, lazy);
+ (void)i1;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d1 = acceptor1.async_wait(socket_base::wait_write, dlazy);
+ (void)d1;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ acceptor1.accept(peer_socket);
+ acceptor1.accept(peer_socket, ec);
+ acceptor1.accept(peer_socket, peer_endpoint);
+ acceptor1.accept(peer_socket, peer_endpoint, ec);
+
+#if defined(ASIO_HAS_MOVE)
+ peer_socket = acceptor1.accept();
+ peer_socket = acceptor1.accept(ioc);
+ peer_socket = acceptor1.accept(peer_endpoint);
+ peer_socket = acceptor1.accept(ioc, peer_endpoint);
+ (void)peer_socket;
+#endif // defined(ASIO_HAS_MOVE)
+
+ acceptor1.async_accept(peer_socket, accept_handler());
+ acceptor1.async_accept(peer_socket, peer_endpoint, accept_handler());
+ int i2 = acceptor1.async_accept(peer_socket, lazy);
+ (void)i2;
+ int i3 = acceptor1.async_accept(peer_socket, peer_endpoint, lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d2 = acceptor1.async_accept(peer_socket, dlazy);
+ (void)d2;
+ double d3 = acceptor1.async_accept(peer_socket, peer_endpoint, dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+#if defined(ASIO_HAS_MOVE)
+ acceptor1.async_accept(move_accept_handler());
+ acceptor1.async_accept(ioc, move_accept_handler());
+ acceptor1.async_accept(peer_endpoint, move_accept_handler());
+ acceptor1.async_accept(ioc, peer_endpoint, move_accept_handler());
+#endif // defined(ASIO_HAS_MOVE)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_acceptor_compile
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_acceptor_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::tcp::acceptor
+// class.
+
+namespace ip_tcp_acceptor_runtime {
+
+void handle_accept(const asio::error_code& err)
+{
+ ASIO_CHECK(!err);
+}
+
+void handle_connect(const asio::error_code& err)
+{
+ ASIO_CHECK(!err);
+}
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+
+ ip::tcp::acceptor acceptor(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0));
+ ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(ip::address_v4::loopback());
+
+ ip::tcp::socket client_side_socket(ioc);
+ ip::tcp::socket server_side_socket(ioc);
+
+ client_side_socket.connect(server_endpoint);
+ acceptor.accept(server_side_socket);
+
+ client_side_socket.close();
+ server_side_socket.close();
+
+ client_side_socket.connect(server_endpoint);
+ ip::tcp::endpoint client_endpoint;
+ acceptor.accept(server_side_socket, client_endpoint);
+
+ ip::tcp::endpoint client_side_local_endpoint
+ = client_side_socket.local_endpoint();
+ ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port());
+
+ ip::tcp::endpoint server_side_remote_endpoint
+ = server_side_socket.remote_endpoint();
+ ASIO_CHECK(server_side_remote_endpoint.port()
+ == client_endpoint.port());
+
+ client_side_socket.close();
+ server_side_socket.close();
+
+ acceptor.async_accept(server_side_socket, &handle_accept);
+ client_side_socket.async_connect(server_endpoint, &handle_connect);
+
+ ioc.run();
+
+ client_side_socket.close();
+ server_side_socket.close();
+
+ acceptor.async_accept(server_side_socket, client_endpoint, &handle_accept);
+ client_side_socket.async_connect(server_endpoint, &handle_connect);
+
+ ioc.restart();
+ ioc.run();
+
+ client_side_local_endpoint = client_side_socket.local_endpoint();
+ ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port());
+
+ server_side_remote_endpoint = server_side_socket.remote_endpoint();
+ ASIO_CHECK(server_side_remote_endpoint.port()
+ == client_endpoint.port());
+}
+
+} // namespace ip_tcp_acceptor_runtime
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_resolver_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::tcp::resolver compile and link correctly. Runtime failures are ignored.
+
+namespace ip_tcp_resolver_compile {
+
+struct resolve_handler
+{
+ resolve_handler() {}
+ void operator()(const asio::error_code&,
+ asio::ip::tcp::resolver::results_type) {}
+#if defined(ASIO_HAS_MOVE)
+ resolve_handler(resolve_handler&&) {}
+private:
+ resolve_handler(const resolve_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::tcp::resolver::query q(ip::tcp::v4(), "localhost", "0");
+#endif // !defined(ASIO_NO_DEPRECATED)
+ ip::tcp::endpoint e(ip::address_v4::loopback(), 0);
+
+ // basic_resolver constructors.
+
+ ip::tcp::resolver resolver(ioc);
+
+#if defined(ASIO_HAS_MOVE)
+ ip::tcp::resolver resolver2(std::move(resolver));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_resolver operators.
+
+#if defined(ASIO_HAS_MOVE)
+ resolver = ip::tcp::resolver(ioc);
+ resolver = std::move(resolver2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = resolver.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::tcp::resolver::executor_type ex = resolver.get_executor();
+ (void)ex;
+
+ // basic_resolver functions.
+
+ resolver.cancel();
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::tcp::resolver::results_type results1 = resolver.resolve(q);
+ (void)results1;
+
+ ip::tcp::resolver::results_type results2 = resolver.resolve(q, ec);
+ (void)results2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::tcp::resolver::results_type results3 = resolver.resolve("", "");
+ (void)results3;
+
+ ip::tcp::resolver::results_type results4 = resolver.resolve("", "", ec);
+ (void)results4;
+
+ ip::tcp::resolver::results_type results5 =
+ resolver.resolve("", "", ip::tcp::resolver::flags());
+ (void)results5;
+
+ ip::tcp::resolver::results_type results6 =
+ resolver.resolve("", "", ip::tcp::resolver::flags(), ec);
+ (void)results6;
+
+ ip::tcp::resolver::results_type results7 =
+ resolver.resolve(ip::tcp::v4(), "", "");
+ (void)results7;
+
+ ip::tcp::resolver::results_type results8 =
+ resolver.resolve(ip::tcp::v4(), "", "", ec);
+ (void)results8;
+
+ ip::tcp::resolver::results_type results9 =
+ resolver.resolve(ip::tcp::v4(), "", "", ip::tcp::resolver::flags());
+ (void)results9;
+
+ ip::tcp::resolver::results_type results10 =
+ resolver.resolve(ip::tcp::v4(), "", "", ip::tcp::resolver::flags(), ec);
+ (void)results10;
+
+ ip::tcp::resolver::results_type results11 = resolver.resolve(e);
+ (void)results11;
+
+ ip::tcp::resolver::results_type results12 = resolver.resolve(e, ec);
+ (void)results12;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ resolver.async_resolve(q, resolve_handler());
+ int i1 = resolver.async_resolve(q, lazy);
+ (void)i1;
+ double d1 = resolver.async_resolve(q, dlazy);
+ (void)d1;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "", resolve_handler());
+ int i2 = resolver.async_resolve("", "", lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d2 = resolver.async_resolve("", "", dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "",
+ ip::tcp::resolver::flags(), resolve_handler());
+ int i3 = resolver.async_resolve("", "",
+ ip::tcp::resolver::flags(), lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = resolver.async_resolve("", "",
+ ip::tcp::resolver::flags(), dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::tcp::v4(), "", "", resolve_handler());
+ int i4 = resolver.async_resolve(ip::tcp::v4(), "", "", lazy);
+ (void)i4;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d4 = resolver.async_resolve(ip::tcp::v4(), "", "", dlazy);
+ (void)d4;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::tcp::v4(),
+ "", "", ip::tcp::resolver::flags(), resolve_handler());
+ int i5 = resolver.async_resolve(ip::tcp::v4(),
+ "", "", ip::tcp::resolver::flags(), lazy);
+ (void)i5;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d5 = resolver.async_resolve(ip::tcp::v4(),
+ "", "", ip::tcp::resolver::flags(), dlazy);
+ (void)d5;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(e, resolve_handler());
+ int i6 = resolver.async_resolve(e, lazy);
+ (void)i6;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d6 = resolver.async_resolve(e, dlazy);
+ (void)d6;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_resolver_compile
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_resolver_entry_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::tcp::resolver::entry compile and link correctly. Runtime failures are
+// ignored.
+
+namespace ip_tcp_resolver_entry_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+ const ip::tcp::endpoint endpoint;
+ const std::string host_name;
+ const std::string service_name;
+ const std::allocator<char> alloc;
+
+ try
+ {
+ // basic_resolver_entry constructors.
+
+ const ip::basic_resolver_entry<ip::tcp> entry1;
+ ip::basic_resolver_entry<ip::tcp> entry2(endpoint, host_name, service_name);
+ ip::basic_resolver_entry<ip::tcp> entry3(entry1);
+#if defined(ASIO_HAS_MOVE)
+ ip::basic_resolver_entry<ip::tcp> entry4(std::move(entry2));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_resolver_entry functions.
+
+ ip::tcp::endpoint e1 = entry1.endpoint();
+ (void)e1;
+
+ ip::tcp::endpoint e2 = entry1;
+ (void)e2;
+
+ std::string s1 = entry1.host_name();
+ (void)s1;
+
+ std::string s2 = entry1.host_name(alloc);
+ (void)s2;
+
+ std::string s3 = entry1.service_name();
+ (void)s3;
+
+ std::string s4 = entry1.service_name(alloc);
+ (void)s4;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_resolver_entry_compile
+
+//------------------------------------------------------------------------------
+
+// ip_tcp_iostream_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public types and member functions on the
+// class ip::tcp::iostream compile and link correctly. Runtime failures are
+// ignored.
+
+namespace ip_tcp_iostream_compile {
+
+void test()
+{
+#if !defined(ASIO_NO_IOSTREAM)
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ asio::io_context ioc;
+ asio::ip::tcp::socket sock(ioc);
+
+ // basic_socket_iostream typedefs.
+
+ (void)static_cast<ip::tcp::iostream::protocol_type*>(0);
+ (void)static_cast<ip::tcp::iostream::endpoint_type*>(0);
+ (void)static_cast<ip::tcp::iostream::clock_type*>(0);
+ (void)static_cast<ip::tcp::iostream::time_point*>(0);
+ (void)static_cast<ip::tcp::iostream::duration*>(0);
+ (void)static_cast<ip::tcp::iostream::traits_type*>(0);
+
+ // basic_socket_iostream constructors.
+
+ ip::tcp::iostream ios1;
+
+#if defined(ASIO_HAS_MOVE)
+ ip::tcp::iostream ios2(std::move(sock));
+#endif // defined(ASIO_HAS_MOVE)
+
+ ip::tcp::iostream ios3("hostname", "service");
+
+ // basic_socket_iostream operators.
+
+#if defined(ASIO_HAS_MOVE)
+ ios1 = ip::tcp::iostream();
+
+ ios2 = std::move(ios1);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_socket_iostream members.
+
+ ios1.connect("hostname", "service");
+
+ ios1.close();
+
+ (void)static_cast<std::streambuf*>(ios1.rdbuf());
+
+#if defined(ASIO_ENABLE_OLD_SERVICES)
+ basic_socket<ip::tcp, stream_socket_service<ip::tcp> >& sref = ios1.socket();
+#else // defined(ASIO_ENABLE_OLD_SERVICES)
+ basic_socket<ip::tcp>& sref = ios1.socket();
+#endif // defined(ASIO_ENABLE_OLD_SERVICES)
+ (void)sref;
+
+ error_code ec = ios1.error();
+ (void)ec;
+
+ ip::tcp::iostream::time_point tp = ios1.expiry();
+ (void)tp;
+
+ ios1.expires_at(tp);
+
+ ip::tcp::iostream::duration d;
+ ios1.expires_after(d);
+
+ // iostream operators.
+
+ int i = 0;
+ ios1 >> i;
+ ios1 << i;
+#endif // !defined(ASIO_NO_IOSTREAM)
+}
+
+} // namespace ip_tcp_iostream_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/tcp",
+ ASIO_TEST_CASE(ip_tcp_compile::test)
+ ASIO_TEST_CASE(ip_tcp_runtime::test)
+ ASIO_TEST_CASE(ip_tcp_socket_compile::test)
+ ASIO_TEST_CASE(ip_tcp_socket_runtime::test)
+ ASIO_TEST_CASE(ip_tcp_acceptor_compile::test)
+ ASIO_TEST_CASE(ip_tcp_acceptor_runtime::test)
+ ASIO_TEST_CASE(ip_tcp_resolver_compile::test)
+ ASIO_TEST_CASE(ip_tcp_resolver_entry_compile::test)
+ ASIO_TEST_CASE(ip_tcp_resolver_entry_compile::test)
+ ASIO_COMPILE_TEST_CASE(ip_tcp_iostream_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/udp.cpp b/3rdparty/asio/src/tests/unit/ip/udp.cpp
new file mode 100644
index 00000000000..48f9276ce4b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/udp.cpp
@@ -0,0 +1,783 @@
+//
+// udp.cpp
+// ~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/udp.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "../unit_test.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../archetypes/deprecated_async_result.hpp"
+#include "../archetypes/gettable_socket_option.hpp"
+#include "../archetypes/io_control_command.hpp"
+#include "../archetypes/settable_socket_option.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+//------------------------------------------------------------------------------
+
+// ip_udp_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::udp::socket compile and link correctly. Runtime failures are ignored.
+
+namespace ip_udp_socket_compile {
+
+struct connect_handler
+{
+ connect_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ connect_handler(connect_handler&&) {}
+private:
+ connect_handler(const connect_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct wait_handler
+{
+ wait_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ wait_handler(wait_handler&&) {}
+private:
+ wait_handler(const wait_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct send_handler
+{
+ send_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ send_handler(send_handler&&) {}
+private:
+ send_handler(const send_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct receive_handler
+{
+ receive_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ receive_handler(receive_handler&&) {}
+private:
+ receive_handler(const receive_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ archetypes::settable_socket_option<void> settable_socket_option1;
+ archetypes::settable_socket_option<int> settable_socket_option2;
+ archetypes::settable_socket_option<double> settable_socket_option3;
+ archetypes::gettable_socket_option<void> gettable_socket_option1;
+ archetypes::gettable_socket_option<int> gettable_socket_option2;
+ archetypes::gettable_socket_option<double> gettable_socket_option3;
+ archetypes::io_control_command io_control_command;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+
+ // basic_datagram_socket constructors.
+
+ ip::udp::socket socket1(ioc);
+ ip::udp::socket socket2(ioc, ip::udp::v4());
+ ip::udp::socket socket3(ioc, ip::udp::v6());
+ ip::udp::socket socket4(ioc, ip::udp::endpoint(ip::udp::v4(), 0));
+ ip::udp::socket socket5(ioc, ip::udp::endpoint(ip::udp::v6(), 0));
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::udp::socket::native_handle_type native_socket1
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ ip::udp::socket socket6(ioc, ip::udp::v4(), native_socket1);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+#if defined(ASIO_HAS_MOVE)
+ ip::udp::socket socket7(std::move(socket6));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+ socket1 = ip::udp::socket(ioc);
+ socket1 = std::move(socket2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::udp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+ // basic_socket functions.
+
+ ip::udp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ const ip::udp::socket& socket8 = socket1;
+ const ip::udp::socket::lowest_layer_type& lowest_layer2
+ = socket8.lowest_layer();
+ (void)lowest_layer2;
+
+ socket1.open(ip::udp::v4());
+ socket1.open(ip::udp::v6());
+ socket1.open(ip::udp::v4(), ec);
+ socket1.open(ip::udp::v6(), ec);
+
+#if !defined(ASIO_WINDOWS_RUNTIME)
+ ip::udp::socket::native_handle_type native_socket2
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ socket1.assign(ip::udp::v4(), native_socket2);
+ ip::udp::socket::native_handle_type native_socket3
+ = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ socket1.assign(ip::udp::v4(), native_socket3, ec);
+#endif // !defined(ASIO_WINDOWS_RUNTIME)
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ ip::udp::socket::native_handle_type native_socket4
+ = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(ip::udp::endpoint(ip::udp::v4(), 0));
+ socket1.bind(ip::udp::endpoint(ip::udp::v6(), 0));
+ socket1.bind(ip::udp::endpoint(ip::udp::v4(), 0), ec);
+ socket1.bind(ip::udp::endpoint(ip::udp::v6(), 0), ec);
+
+ socket1.connect(ip::udp::endpoint(ip::udp::v4(), 0));
+ socket1.connect(ip::udp::endpoint(ip::udp::v6(), 0));
+ socket1.connect(ip::udp::endpoint(ip::udp::v4(), 0), ec);
+ socket1.connect(ip::udp::endpoint(ip::udp::v6(), 0), ec);
+
+ socket1.async_connect(ip::udp::endpoint(ip::udp::v4(), 0),
+ connect_handler());
+ socket1.async_connect(ip::udp::endpoint(ip::udp::v6(), 0),
+ connect_handler());
+ int i1 = socket1.async_connect(ip::udp::endpoint(ip::udp::v4(), 0), lazy);
+ (void)i1;
+ int i2 = socket1.async_connect(ip::udp::endpoint(ip::udp::v6(), 0), lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d1 = socket1.async_connect(
+ ip::udp::endpoint(ip::udp::v4(), 0), dlazy);
+ (void)d1;
+ double d2 = socket1.async_connect(
+ ip::udp::endpoint(ip::udp::v6(), 0), dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.set_option(settable_socket_option1);
+ socket1.set_option(settable_socket_option1, ec);
+ socket1.set_option(settable_socket_option2);
+ socket1.set_option(settable_socket_option2, ec);
+ socket1.set_option(settable_socket_option3);
+ socket1.set_option(settable_socket_option3, ec);
+
+ socket1.get_option(gettable_socket_option1);
+ socket1.get_option(gettable_socket_option1, ec);
+ socket1.get_option(gettable_socket_option2);
+ socket1.get_option(gettable_socket_option2, ec);
+ socket1.get_option(gettable_socket_option3);
+ socket1.get_option(gettable_socket_option3, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ bool non_blocking1 = socket1.non_blocking();
+ (void)non_blocking1;
+ socket1.non_blocking(true);
+ socket1.non_blocking(false, ec);
+
+ bool non_blocking2 = socket1.native_non_blocking();
+ (void)non_blocking2;
+ socket1.native_non_blocking(true);
+ socket1.native_non_blocking(false, ec);
+
+ ip::udp::endpoint endpoint1 = socket1.local_endpoint();
+ ip::udp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ ip::udp::endpoint endpoint3 = socket1.remote_endpoint();
+ ip::udp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ socket1.wait(socket_base::wait_read);
+ socket1.wait(socket_base::wait_write, ec);
+
+ socket1.async_wait(socket_base::wait_read, wait_handler());
+ int i3 = socket1.async_wait(socket_base::wait_write, lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = socket1.async_wait(socket_base::wait_write, dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_datagram_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler());
+ socket1.async_send(buffer(const_char_buffer), send_handler());
+ socket1.async_send(null_buffers(), send_handler());
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler());
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler());
+ socket1.async_send(null_buffers(), in_flags, send_handler());
+ int i4 = socket1.async_send(buffer(mutable_char_buffer), lazy);
+ (void)i4;
+ int i5 = socket1.async_send(buffer(const_char_buffer), lazy);
+ (void)i5;
+ int i6 = socket1.async_send(null_buffers(), lazy);
+ (void)i6;
+ int i7 = socket1.async_send(buffer(mutable_char_buffer), in_flags, lazy);
+ (void)i7;
+ int i8 = socket1.async_send(buffer(const_char_buffer), in_flags, lazy);
+ (void)i8;
+ int i9 = socket1.async_send(null_buffers(), in_flags, lazy);
+ (void)i9;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d4 = socket1.async_send(buffer(mutable_char_buffer), dlazy);
+ (void)d4;
+ double d5 = socket1.async_send(buffer(const_char_buffer), dlazy);
+ (void)d5;
+ double d6 = socket1.async_send(null_buffers(), dlazy);
+ (void)d6;
+ double d7 = socket1.async_send(
+ buffer(mutable_char_buffer), in_flags, dlazy);
+ (void)d7;
+ double d8 = socket1.async_send(buffer(const_char_buffer), in_flags, dlazy);
+ (void)d8;
+ double d9 = socket1.async_send(null_buffers(), in_flags, dlazy);
+ (void)d9;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0));
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0));
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0));
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0));
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0));
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0));
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
+ socket1.send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
+
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
+ socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
+ int i10 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), lazy);
+ (void)i10;
+ int i11 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), lazy);
+ (void)i11;
+ int i12 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), lazy);
+ (void)i12;
+ int i13 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), lazy);
+ (void)i13;
+ int i14 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), lazy);
+ (void)i14;
+ int i15 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), lazy);
+ (void)i15;
+ int i16 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
+ (void)i16;
+ int i17 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
+ (void)i17;
+ int i18 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
+ (void)i18;
+ int i19 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
+ (void)i19;
+ int i20 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
+ (void)i20;
+ int i21 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
+ (void)i21;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d10 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), dlazy);
+ (void)d10;
+ double d11 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), dlazy);
+ (void)d11;
+ double d12 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), dlazy);
+ (void)d12;
+ double d13 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), dlazy);
+ (void)d13;
+ double d14 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), dlazy);
+ (void)d14;
+ double d15 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), dlazy);
+ (void)d15;
+ double d16 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, dlazy);
+ (void)d16;
+ double d17 = socket1.async_send_to(buffer(mutable_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, dlazy);
+ (void)d17;
+ double d18 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, dlazy);
+ (void)d18;
+ double d19 = socket1.async_send_to(buffer(const_char_buffer),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, dlazy);
+ (void)d19;
+ double d20 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v4(), 0), in_flags, dlazy);
+ (void)d20;
+ double d21 = socket1.async_send_to(null_buffers(),
+ ip::udp::endpoint(ip::udp::v6(), 0), in_flags, dlazy);
+ (void)d21;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler());
+ socket1.async_receive(null_buffers(), receive_handler());
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler());
+ socket1.async_receive(null_buffers(), in_flags, receive_handler());
+ int i22 = socket1.async_receive(buffer(mutable_char_buffer), lazy);
+ (void)i22;
+ int i23 = socket1.async_receive(null_buffers(), lazy);
+ (void)i23;
+ int i24 = socket1.async_receive(buffer(mutable_char_buffer),
+ in_flags, lazy);
+ (void)i24;
+ int i25 = socket1.async_receive(null_buffers(), in_flags, lazy);
+ (void)i25;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d22 = socket1.async_receive(buffer(mutable_char_buffer), dlazy);
+ (void)d22;
+ double d23 = socket1.async_receive(null_buffers(), dlazy);
+ (void)d23;
+ double d24 = socket1.async_receive(buffer(mutable_char_buffer),
+ in_flags, dlazy);
+ (void)d24;
+ double d25 = socket1.async_receive(null_buffers(), in_flags, dlazy);
+ (void)d25;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::udp::endpoint endpoint;
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+ socket1.receive_from(null_buffers(), endpoint);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+ socket1.receive_from(null_buffers(), endpoint, in_flags);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+ socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, receive_handler());
+ socket1.async_receive_from(null_buffers(),
+ endpoint, receive_handler());
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, receive_handler());
+ socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, receive_handler());
+ int i26 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, lazy);
+ (void)i26;
+ int i27 = socket1.async_receive_from(null_buffers(),
+ endpoint, lazy);
+ (void)i27;
+ int i28 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, lazy);
+ (void)i28;
+ int i29 = socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, lazy);
+ (void)i29;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d26 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, dlazy);
+ (void)d26;
+ double d27 = socket1.async_receive_from(null_buffers(),
+ endpoint, dlazy);
+ (void)d27;
+ double d28 = socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, dlazy);
+ (void)d28;
+ double d29 = socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, dlazy);
+ (void)d29;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_udp_socket_compile
+
+//------------------------------------------------------------------------------
+
+// ip_udp_socket_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::udp::socket class.
+
+namespace ip_udp_socket_runtime {
+
+void handle_send(size_t expected_bytes_sent,
+ const asio::error_code& err, size_t bytes_sent)
+{
+ ASIO_CHECK(!err);
+ ASIO_CHECK(expected_bytes_sent == bytes_sent);
+}
+
+void handle_recv(size_t expected_bytes_recvd,
+ const asio::error_code& err, size_t bytes_recvd)
+{
+ ASIO_CHECK(!err);
+ ASIO_CHECK(expected_bytes_recvd == bytes_recvd);
+}
+
+void test()
+{
+ using namespace std; // For memcmp and memset.
+ using namespace asio;
+ namespace ip = asio::ip;
+
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ io_context ioc;
+
+ ip::udp::socket s1(ioc, ip::udp::endpoint(ip::udp::v4(), 0));
+ ip::udp::endpoint target_endpoint = s1.local_endpoint();
+ target_endpoint.address(ip::address_v4::loopback());
+
+ ip::udp::socket s2(ioc);
+ s2.open(ip::udp::v4());
+ s2.bind(ip::udp::endpoint(ip::udp::v4(), 0));
+ char send_msg[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ s2.send_to(buffer(send_msg, sizeof(send_msg)), target_endpoint);
+
+ char recv_msg[sizeof(send_msg)];
+ ip::udp::endpoint sender_endpoint;
+ size_t bytes_recvd = s1.receive_from(buffer(recv_msg, sizeof(recv_msg)),
+ sender_endpoint);
+
+ ASIO_CHECK(bytes_recvd == sizeof(send_msg));
+ ASIO_CHECK(memcmp(send_msg, recv_msg, sizeof(send_msg)) == 0);
+
+ memset(recv_msg, 0, sizeof(recv_msg));
+
+ target_endpoint = sender_endpoint;
+ s1.async_send_to(buffer(send_msg, sizeof(send_msg)), target_endpoint,
+ bindns::bind(handle_send, sizeof(send_msg), _1, _2));
+ s2.async_receive_from(buffer(recv_msg, sizeof(recv_msg)), sender_endpoint,
+ bindns::bind(handle_recv, sizeof(recv_msg), _1, _2));
+
+ ioc.run();
+
+ ASIO_CHECK(memcmp(send_msg, recv_msg, sizeof(send_msg)) == 0);
+}
+
+} // namespace ip_udp_socket_runtime
+
+//------------------------------------------------------------------------------
+
+// ip_udp_resolver_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::udp::resolver compile and link correctly. Runtime failures are ignored.
+
+namespace ip_udp_resolver_compile {
+
+struct resolve_handler
+{
+ resolve_handler() {}
+ void operator()(const asio::error_code&,
+ asio::ip::udp::resolver::results_type) {}
+#if defined(ASIO_HAS_MOVE)
+ resolve_handler(resolve_handler&&) {}
+private:
+ resolve_handler(const resolve_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ archetypes::lazy_handler lazy;
+#if !defined(ASIO_NO_DEPRECATED)
+ archetypes::deprecated_lazy_handler dlazy;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ asio::error_code ec;
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::udp::resolver::query q(ip::udp::v4(), "localhost", "0");
+#endif // !defined(ASIO_NO_DEPRECATED)
+ ip::udp::endpoint e(ip::address_v4::loopback(), 0);
+
+ // basic_resolver constructors.
+
+ ip::udp::resolver resolver(ioc);
+
+#if defined(ASIO_HAS_MOVE)
+ ip::udp::resolver resolver2(std::move(resolver));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_resolver operators.
+
+#if defined(ASIO_HAS_MOVE)
+ resolver = ip::udp::resolver(ioc);
+ resolver = std::move(resolver2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = resolver.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::udp::resolver::executor_type ex = resolver.get_executor();
+ (void)ex;
+
+ // basic_resolver functions.
+
+ resolver.cancel();
+
+#if !defined(ASIO_NO_DEPRECATED)
+ ip::udp::resolver::results_type results1 = resolver.resolve(q);
+ (void)results1;
+
+ ip::udp::resolver::results_type results2 = resolver.resolve(q, ec);
+ (void)results2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ ip::udp::resolver::results_type results3 = resolver.resolve("", "");
+ (void)results3;
+
+ ip::udp::resolver::results_type results4 = resolver.resolve("", "", ec);
+ (void)results4;
+
+ ip::udp::resolver::results_type results5 =
+ resolver.resolve("", "", ip::udp::resolver::flags());
+ (void)results5;
+
+ ip::udp::resolver::results_type results6 =
+ resolver.resolve("", "", ip::udp::resolver::flags(), ec);
+ (void)results6;
+
+ ip::udp::resolver::results_type results7 =
+ resolver.resolve(ip::udp::v4(), "", "");
+ (void)results7;
+
+ ip::udp::resolver::results_type results8 =
+ resolver.resolve(ip::udp::v4(), "", "", ec);
+ (void)results8;
+
+ ip::udp::resolver::results_type results9 =
+ resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags());
+ (void)results9;
+
+ ip::udp::resolver::results_type results10 =
+ resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags(), ec);
+ (void)results10;
+
+ ip::udp::resolver::results_type results11 = resolver.resolve(e);
+ (void)results11;
+
+ ip::udp::resolver::results_type results12 = resolver.resolve(e, ec);
+ (void)results12;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ resolver.async_resolve(q, resolve_handler());
+ int i1 = resolver.async_resolve(q, lazy);
+ (void)i1;
+ double d1 = resolver.async_resolve(q, dlazy);
+ (void)d1;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "", resolve_handler());
+ int i2 = resolver.async_resolve("", "", lazy);
+ (void)i2;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d2 = resolver.async_resolve("", "", dlazy);
+ (void)d2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve("", "",
+ ip::udp::resolver::flags(), resolve_handler());
+ int i3 = resolver.async_resolve("", "",
+ ip::udp::resolver::flags(), lazy);
+ (void)i3;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d3 = resolver.async_resolve("", "",
+ ip::udp::resolver::flags(), dlazy);
+ (void)d3;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::udp::v4(), "", "", resolve_handler());
+ int i4 = resolver.async_resolve(ip::udp::v4(), "", "", lazy);
+ (void)i4;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d4 = resolver.async_resolve(ip::udp::v4(), "", "", dlazy);
+ (void)d4;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(ip::udp::v4(),
+ "", "", ip::udp::resolver::flags(), resolve_handler());
+ int i5 = resolver.async_resolve(ip::udp::v4(),
+ "", "", ip::udp::resolver::flags(), lazy);
+ (void)i5;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d5 = resolver.async_resolve(ip::udp::v4(),
+ "", "", ip::udp::resolver::flags(), dlazy);
+ (void)d5;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ resolver.async_resolve(e, resolve_handler());
+ int i6 = resolver.async_resolve(e, lazy);
+ (void)i6;
+#if !defined(ASIO_NO_DEPRECATED)
+ double d6 = resolver.async_resolve(e, dlazy);
+ (void)d6;
+#endif // !defined(ASIO_NO_DEPRECATED)
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_udp_resolver_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/udp",
+ ASIO_TEST_CASE(ip_udp_socket_compile::test)
+ ASIO_TEST_CASE(ip_udp_socket_runtime::test)
+ ASIO_TEST_CASE(ip_udp_resolver_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/unicast.cpp b/3rdparty/asio/src/tests/unit/ip/unicast.cpp
new file mode 100644
index 00000000000..669e2727ceb
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/unicast.cpp
@@ -0,0 +1,171 @@
+//
+// unicast.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/unicast.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/ip/udp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// ip_unicast_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all nested classes, enums and constants in
+// ip::unicast compile and link correctly. Runtime failures are ignored.
+
+namespace ip_unicast_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::udp::socket sock(ioc);
+
+ // hops class.
+
+ ip::unicast::hops hops1(1024);
+ sock.set_option(hops1);
+ ip::unicast::hops hops2;
+ sock.get_option(hops2);
+ hops1 = 1;
+ (void)static_cast<int>(hops1.value());
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_unicast_compile
+
+//------------------------------------------------------------------------------
+
+// ip_unicast_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the socket options defined
+// in the ip::unicast namespace.
+
+namespace ip_unicast_runtime {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+ asio::error_code ec;
+
+ ip::udp::endpoint ep_v4(ip::address_v4::loopback(), 0);
+ ip::udp::socket sock_v4(ioc);
+ sock_v4.open(ep_v4.protocol(), ec);
+ sock_v4.bind(ep_v4, ec);
+ bool have_v4 = !ec;
+
+ ip::udp::endpoint ep_v6(ip::address_v6::loopback(), 0);
+ ip::udp::socket sock_v6(ioc);
+ sock_v6.open(ep_v6.protocol(), ec);
+ sock_v6.bind(ep_v6, ec);
+ bool have_v6 = !ec;
+
+ ASIO_CHECK(have_v4 || have_v6);
+
+ // hops class.
+
+ if (have_v4)
+ {
+ ip::unicast::hops hops1(1);
+ ASIO_CHECK(hops1.value() == 1);
+ sock_v4.set_option(hops1, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::unicast::hops hops2;
+ sock_v4.get_option(hops2, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(hops2.value() == 1);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::unicast::hops hops3(255);
+ ASIO_CHECK(hops3.value() == 255);
+ sock_v4.set_option(hops3, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ ip::unicast::hops hops4;
+ sock_v4.get_option(hops4, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(hops4.value() == 255);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ }
+
+ if (have_v6)
+ {
+ ip::unicast::hops hops1(1);
+ ASIO_CHECK(hops1.value() == 1);
+ sock_v6.set_option(hops1, ec);
+ ASIO_CHECK(!ec);
+
+ ip::unicast::hops hops2;
+ sock_v6.get_option(hops2, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(hops2.value() == 1);
+
+ ip::unicast::hops hops3(255);
+ ASIO_CHECK(hops3.value() == 255);
+ sock_v6.set_option(hops3, ec);
+ ASIO_CHECK(!ec);
+
+ ip::unicast::hops hops4;
+ sock_v6.get_option(hops4, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(hops4.value() == 255);
+ }
+}
+
+} // namespace ip_unicast_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/unicast",
+ ASIO_TEST_CASE(ip_unicast_compile::test)
+ ASIO_TEST_CASE(ip_unicast_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ip/v6_only.cpp b/3rdparty/asio/src/tests/unit/ip/v6_only.cpp
new file mode 100644
index 00000000000..951540f889b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ip/v6_only.cpp
@@ -0,0 +1,135 @@
+//
+// v6_only.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ip/v6_only.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/ip/udp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// ip_v6_only_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that the ip::v6_only socket option compiles and
+// link correctly. Runtime failures are ignored.
+
+namespace ip_v6_only_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::udp::socket sock(ioc);
+
+ // v6_only class.
+
+ ip::v6_only v6_only1(true);
+ sock.set_option(v6_only1);
+ ip::v6_only v6_only2;
+ sock.get_option(v6_only2);
+ v6_only1 = true;
+ (void)static_cast<bool>(v6_only1);
+ (void)static_cast<bool>(!v6_only1);
+ (void)static_cast<bool>(v6_only1.value());
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_v6_only_compile
+
+//------------------------------------------------------------------------------
+
+// ip_v6_only_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::v6_only socket
+// option.
+
+namespace ip_v6_only_runtime {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+ asio::error_code ec;
+
+ ip::tcp::endpoint ep_v6(ip::address_v6::loopback(), 0);
+ ip::tcp::acceptor acceptor_v6(ioc);
+ acceptor_v6.open(ep_v6.protocol(), ec);
+ acceptor_v6.bind(ep_v6, ec);
+ bool have_v6 = !ec;
+ acceptor_v6.close(ec);
+ acceptor_v6.open(ep_v6.protocol(), ec);
+
+ if (have_v6)
+ {
+ ip::v6_only v6_only1;
+ acceptor_v6.get_option(v6_only1, ec);
+ ASIO_CHECK(!ec);
+ bool have_dual_stack = !v6_only1.value();
+
+ if (have_dual_stack)
+ {
+ ip::v6_only v6_only2(false);
+ ASIO_CHECK(!v6_only2.value());
+ ASIO_CHECK(!static_cast<bool>(v6_only2));
+ ASIO_CHECK(!v6_only2);
+ acceptor_v6.set_option(v6_only2, ec);
+ ASIO_CHECK(!ec);
+
+ ip::v6_only v6_only3;
+ acceptor_v6.get_option(v6_only3, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(!v6_only3.value());
+ ASIO_CHECK(!static_cast<bool>(v6_only3));
+ ASIO_CHECK(!v6_only3);
+
+ ip::v6_only v6_only4(true);
+ ASIO_CHECK(v6_only4.value());
+ ASIO_CHECK(static_cast<bool>(v6_only4));
+ ASIO_CHECK(!!v6_only4);
+ acceptor_v6.set_option(v6_only4, ec);
+ ASIO_CHECK(!ec);
+
+ ip::v6_only v6_only5;
+ acceptor_v6.get_option(v6_only5, ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(v6_only5.value());
+ ASIO_CHECK(static_cast<bool>(v6_only5));
+ ASIO_CHECK(!!v6_only5);
+ }
+ }
+}
+
+} // namespace ip_v6_only_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ip/v6_only",
+ ASIO_TEST_CASE(ip_v6_only_compile::test)
+ ASIO_TEST_CASE(ip_v6_only_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/is_read_buffered.cpp b/3rdparty/asio/src/tests/unit/is_read_buffered.cpp
new file mode 100644
index 00000000000..151e483a020
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/is_read_buffered.cpp
@@ -0,0 +1,129 @@
+//
+// is_read_buffered.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/is_read_buffered.hpp"
+
+#include "asio/buffered_read_stream.hpp"
+#include "asio/buffered_write_stream.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "unit_test.hpp"
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_stream
+{
+public:
+ typedef asio::io_context io_context_type;
+
+ typedef test_stream lowest_layer_type;
+
+ typedef io_context_type::executor_type executor_type;
+
+ test_stream(asio::io_context& io_context)
+ : io_context_(io_context)
+ {
+ }
+
+ io_context_type& io_context()
+ {
+ return io_context_;
+ }
+
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ template <typename Const_Buffers>
+ size_t write(const Const_Buffers&)
+ {
+ return 0;
+ }
+
+ template <typename Const_Buffers>
+ size_t write(const Const_Buffers&, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return 0;
+ }
+
+ template <typename Const_Buffers, typename Handler>
+ void async_write(const Const_Buffers&, Handler handler)
+ {
+ asio::error_code error;
+ asio::post(io_context_,
+ asio::detail::bind_handler(handler, error, 0));
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read(const Mutable_Buffers&)
+ {
+ return 0;
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read(const Mutable_Buffers&, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return 0;
+ }
+
+ template <typename Mutable_Buffers, typename Handler>
+ void async_read(const Mutable_Buffers&, Handler handler)
+ {
+ asio::error_code error;
+ asio::post(io_context_,
+ asio::detail::bind_handler(handler, error, 0));
+ }
+
+private:
+ io_context_type& io_context_;
+};
+
+void is_read_buffered_test()
+{
+ ASIO_CHECK(!asio::is_read_buffered<
+ asio::ip::tcp::socket>::value);
+
+ ASIO_CHECK(!!asio::is_read_buffered<
+ asio::buffered_read_stream<
+ asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!asio::is_read_buffered<
+ asio::buffered_write_stream<
+ asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!!asio::is_read_buffered<
+ asio::buffered_stream<asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!asio::is_read_buffered<test_stream>::value);
+
+ ASIO_CHECK(!!asio::is_read_buffered<
+ asio::buffered_read_stream<test_stream> >::value);
+
+ ASIO_CHECK(!asio::is_read_buffered<
+ asio::buffered_write_stream<test_stream> >::value);
+
+ ASIO_CHECK(!!asio::is_read_buffered<
+ asio::buffered_stream<test_stream> >::value);
+}
+
+ASIO_TEST_SUITE
+(
+ "is_read_buffered",
+ ASIO_TEST_CASE(is_read_buffered_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/is_write_buffered.cpp b/3rdparty/asio/src/tests/unit/is_write_buffered.cpp
new file mode 100644
index 00000000000..165f6e74080
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/is_write_buffered.cpp
@@ -0,0 +1,129 @@
+//
+// is_write_buffered.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/is_write_buffered.hpp"
+
+#include "asio/buffered_read_stream.hpp"
+#include "asio/buffered_write_stream.hpp"
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "unit_test.hpp"
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_stream
+{
+public:
+ typedef asio::io_context io_context_type;
+
+ typedef test_stream lowest_layer_type;
+
+ typedef io_context_type::executor_type executor_type;
+
+ test_stream(asio::io_context& io_context)
+ : io_context_(io_context)
+ {
+ }
+
+ io_context_type& io_context()
+ {
+ return io_context_;
+ }
+
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ template <typename Const_Buffers>
+ size_t write(const Const_Buffers&)
+ {
+ return 0;
+ }
+
+ template <typename Const_Buffers>
+ size_t write(const Const_Buffers&, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return 0;
+ }
+
+ template <typename Const_Buffers, typename Handler>
+ void async_write(const Const_Buffers&, Handler handler)
+ {
+ asio::error_code error;
+ asio::post(io_context_,
+ asio::detail::bind_handler(handler, error, 0));
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read(const Mutable_Buffers&)
+ {
+ return 0;
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read(const Mutable_Buffers&, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return 0;
+ }
+
+ template <typename Mutable_Buffers, typename Handler>
+ void async_read(const Mutable_Buffers&, Handler handler)
+ {
+ asio::error_code error;
+ asio::post(io_context_,
+ asio::detail::bind_handler(handler, error, 0));
+ }
+
+private:
+ io_context_type& io_context_;
+};
+
+void is_write_buffered_test()
+{
+ ASIO_CHECK(!asio::is_write_buffered<
+ asio::ip::tcp::socket>::value);
+
+ ASIO_CHECK(!asio::is_write_buffered<
+ asio::buffered_read_stream<
+ asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!!asio::is_write_buffered<
+ asio::buffered_write_stream<
+ asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!!asio::is_write_buffered<
+ asio::buffered_stream<asio::ip::tcp::socket> >::value);
+
+ ASIO_CHECK(!asio::is_write_buffered<test_stream>::value);
+
+ ASIO_CHECK(!asio::is_write_buffered<
+ asio::buffered_read_stream<test_stream> >::value);
+
+ ASIO_CHECK(!!asio::is_write_buffered<
+ asio::buffered_write_stream<test_stream> >::value);
+
+ ASIO_CHECK(!!asio::is_write_buffered<
+ asio::buffered_stream<test_stream> >::value);
+}
+
+ASIO_TEST_SUITE
+(
+ "is_write_buffered",
+ ASIO_TEST_CASE(is_write_buffered_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/local/.gitignore b/3rdparty/asio/src/tests/unit/local/.gitignore
new file mode 100644
index 00000000000..f2d0faff70d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/local/.gitignore
@@ -0,0 +1,13 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+basic_endpoint
+connect_pair
+datagram_protocol
+stream_protocol
diff --git a/3rdparty/asio/src/tests/unit/local/basic_endpoint.cpp b/3rdparty/asio/src/tests/unit/local/basic_endpoint.cpp
new file mode 100644
index 00000000000..aa76637ab1e
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/local/basic_endpoint.cpp
@@ -0,0 +1,25 @@
+//
+// basic_endpoint.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/local/basic_endpoint.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "local/basic_endpoint",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/local/connect_pair.cpp b/3rdparty/asio/src/tests/unit/local/connect_pair.cpp
new file mode 100644
index 00000000000..31a34af67f6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/local/connect_pair.cpp
@@ -0,0 +1,76 @@
+//
+// connect_pair.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/local/connect_pair.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/local/datagram_protocol.hpp"
+#include "asio/local/stream_protocol.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// local_connect_pair_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all host_name functions compile and link
+// correctly. Runtime failures are ignored.
+
+namespace local_connect_pair_compile {
+
+void test()
+{
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+ using namespace asio;
+ namespace local = asio::local;
+ typedef local::datagram_protocol dp;
+ typedef local::stream_protocol sp;
+
+ try
+ {
+ asio::io_context io_context;
+ asio::error_code ec1;
+
+ dp::socket s1(io_context);
+ dp::socket s2(io_context);
+ local::connect_pair(s1, s2);
+
+ dp::socket s3(io_context);
+ dp::socket s4(io_context);
+ local::connect_pair(s3, s4, ec1);
+
+ sp::socket s5(io_context);
+ sp::socket s6(io_context);
+ local::connect_pair(s5, s6);
+
+ sp::socket s7(io_context);
+ sp::socket s8(io_context);
+ local::connect_pair(s7, s8, ec1);
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
+}
+
+} // namespace local_connect_pair_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "local/connect_pair",
+ ASIO_TEST_CASE(local_connect_pair_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/local/datagram_protocol.cpp b/3rdparty/asio/src/tests/unit/local/datagram_protocol.cpp
new file mode 100644
index 00000000000..f685a8220a4
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/local/datagram_protocol.cpp
@@ -0,0 +1,236 @@
+//
+// datagram_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/local/datagram_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// local_datagram_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// local::datagram_socket::socket compile and link correctly. Runtime failures
+// are ignored.
+
+namespace local_datagram_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+ using namespace asio;
+ namespace local = asio::local;
+ typedef local::datagram_protocol dp;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ socket_base::send_buffer_size socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_datagram_socket constructors.
+
+ dp::socket socket1(ioc);
+ dp::socket socket2(ioc, dp());
+ dp::socket socket3(ioc, dp::endpoint(""));
+ int native_socket1 = ::socket(AF_UNIX, SOCK_DGRAM, 0);
+ dp::socket socket4(ioc, dp(), native_socket1);
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ dp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+ // basic_socket functions.
+
+ dp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(dp());
+ socket1.open(dp(), ec);
+
+ int native_socket2 = ::socket(AF_UNIX, SOCK_DGRAM, 0);
+ socket1.assign(dp(), native_socket2);
+ int native_socket3 = ::socket(AF_UNIX, SOCK_DGRAM, 0);
+ socket1.assign(dp(), native_socket3, ec);
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ dp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(dp::endpoint(""));
+ socket1.bind(dp::endpoint(""), ec);
+
+ socket1.connect(dp::endpoint(""));
+ socket1.connect(dp::endpoint(""), ec);
+
+ socket1.async_connect(dp::endpoint(""), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ dp::endpoint endpoint1 = socket1.local_endpoint();
+ dp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ dp::endpoint endpoint3 = socket1.remote_endpoint();
+ dp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_datagram_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler);
+ socket1.async_send(buffer(const_char_buffer), send_handler);
+ socket1.async_send(null_buffers(), send_handler);
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint(""));
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint(""));
+ socket1.send_to(null_buffers(),
+ dp::endpoint(""));
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint(""), in_flags);
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint(""), in_flags);
+ socket1.send_to(null_buffers(),
+ dp::endpoint(""), in_flags);
+ socket1.send_to(buffer(mutable_char_buffer),
+ dp::endpoint(""), in_flags, ec);
+ socket1.send_to(buffer(const_char_buffer),
+ dp::endpoint(""), in_flags, ec);
+ socket1.send_to(null_buffers(),
+ dp::endpoint(""), in_flags, ec);
+
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ dp::endpoint(""), send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ dp::endpoint(""), send_handler);
+ socket1.async_send_to(null_buffers(),
+ dp::endpoint(""), send_handler);
+ socket1.async_send_to(buffer(mutable_char_buffer),
+ dp::endpoint(""), in_flags, send_handler);
+ socket1.async_send_to(buffer(const_char_buffer),
+ dp::endpoint(""), in_flags, send_handler);
+ socket1.async_send_to(null_buffers(),
+ dp::endpoint(""), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+ socket1.async_receive(null_buffers(), receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+ dp::endpoint endpoint;
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+ socket1.receive_from(null_buffers(), endpoint);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+ socket1.receive_from(null_buffers(), endpoint, in_flags);
+ socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+ socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, receive_handler);
+ socket1.async_receive_from(buffer(mutable_char_buffer),
+ endpoint, in_flags, receive_handler);
+ socket1.async_receive_from(null_buffers(),
+ endpoint, in_flags, receive_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
+}
+
+} // namespace local_datagram_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "local/datagram_protocol",
+ ASIO_TEST_CASE(local_datagram_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/local/stream_protocol.cpp b/3rdparty/asio/src/tests/unit/local/stream_protocol.cpp
new file mode 100644
index 00000000000..c22ba410cdb
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/local/stream_protocol.cpp
@@ -0,0 +1,213 @@
+//
+// stream_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/local/stream_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_context.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// local_stream_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// local::stream_protocol::socket compile and link correctly. Runtime failures
+// are ignored.
+
+namespace local_stream_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_LOCAL_SOCKETS)
+ using namespace asio;
+ namespace local = asio::local;
+ typedef local::stream_protocol sp;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ socket_base::message_flags in_flags = 0;
+ socket_base::keep_alive socket_option;
+ socket_base::bytes_readable io_control_command;
+ asio::error_code ec;
+
+ // basic_stream_socket constructors.
+
+ sp::socket socket1(ioc);
+ sp::socket socket2(ioc, sp());
+ sp::socket socket3(ioc, sp::endpoint(""));
+ int native_socket1 = ::socket(AF_UNIX, SOCK_STREAM, 0);
+ sp::socket socket4(ioc, sp(), native_socket1);
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = socket1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ sp::socket::executor_type ex = socket1.get_executor();
+ (void)ex;
+
+ // basic_socket functions.
+
+ sp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+ (void)lowest_layer;
+
+ socket1.open(sp());
+ socket1.open(sp(), ec);
+
+ int native_socket2 = ::socket(AF_UNIX, SOCK_STREAM, 0);
+ socket1.assign(sp(), native_socket2);
+ int native_socket3 = ::socket(AF_UNIX, SOCK_STREAM, 0);
+ socket1.assign(sp(), native_socket3, ec);
+
+ bool is_open = socket1.is_open();
+ (void)is_open;
+
+ socket1.close();
+ socket1.close(ec);
+
+ sp::socket::native_handle_type native_socket4 = socket1.native_handle();
+ (void)native_socket4;
+
+ socket1.cancel();
+ socket1.cancel(ec);
+
+ bool at_mark1 = socket1.at_mark();
+ (void)at_mark1;
+ bool at_mark2 = socket1.at_mark(ec);
+ (void)at_mark2;
+
+ std::size_t available1 = socket1.available();
+ (void)available1;
+ std::size_t available2 = socket1.available(ec);
+ (void)available2;
+
+ socket1.bind(sp::endpoint(""));
+ socket1.bind(sp::endpoint(""), ec);
+
+ socket1.connect(sp::endpoint(""));
+ socket1.connect(sp::endpoint(""), ec);
+
+ socket1.async_connect(sp::endpoint(""), connect_handler);
+
+ socket1.set_option(socket_option);
+ socket1.set_option(socket_option, ec);
+
+ socket1.get_option(socket_option);
+ socket1.get_option(socket_option, ec);
+
+ socket1.io_control(io_control_command);
+ socket1.io_control(io_control_command, ec);
+
+ sp::endpoint endpoint1 = socket1.local_endpoint();
+ sp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+ sp::endpoint endpoint3 = socket1.remote_endpoint();
+ sp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+ socket1.shutdown(socket_base::shutdown_both);
+ socket1.shutdown(socket_base::shutdown_both, ec);
+
+ // basic_stream_socket functions.
+
+ socket1.send(buffer(mutable_char_buffer));
+ socket1.send(buffer(const_char_buffer));
+ socket1.send(null_buffers());
+ socket1.send(buffer(mutable_char_buffer), in_flags);
+ socket1.send(buffer(const_char_buffer), in_flags);
+ socket1.send(null_buffers(), in_flags);
+ socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.send(buffer(const_char_buffer), in_flags, ec);
+ socket1.send(null_buffers(), in_flags, ec);
+
+ socket1.async_send(buffer(mutable_char_buffer), send_handler);
+ socket1.async_send(buffer(const_char_buffer), send_handler);
+ socket1.async_send(null_buffers(), send_handler);
+ socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+ socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+ socket1.async_send(null_buffers(), in_flags, send_handler);
+
+ socket1.receive(buffer(mutable_char_buffer));
+ socket1.receive(null_buffers());
+ socket1.receive(buffer(mutable_char_buffer), in_flags);
+ socket1.receive(null_buffers(), in_flags);
+ socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+ socket1.receive(null_buffers(), in_flags, ec);
+
+ socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+ socket1.async_receive(null_buffers(), receive_handler);
+ socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+ receive_handler);
+ socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+ socket1.write_some(buffer(mutable_char_buffer));
+ socket1.write_some(buffer(const_char_buffer));
+ socket1.write_some(null_buffers());
+ socket1.write_some(buffer(mutable_char_buffer), ec);
+ socket1.write_some(buffer(const_char_buffer), ec);
+ socket1.write_some(null_buffers(), ec);
+
+ socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
+ socket1.async_write_some(buffer(const_char_buffer), write_some_handler);
+ socket1.async_write_some(null_buffers(), write_some_handler);
+
+ socket1.read_some(buffer(mutable_char_buffer));
+ socket1.read_some(buffer(mutable_char_buffer), ec);
+ socket1.read_some(null_buffers(), ec);
+
+ socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+ socket1.async_read_some(null_buffers(), read_some_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_LOCAL_SOCKETS)
+}
+
+} // namespace local_stream_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "local/stream_protocol",
+ ASIO_TEST_CASE(local_stream_protocol_socket_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/packaged_task.cpp b/3rdparty/asio/src/tests/unit/packaged_task.cpp
new file mode 100644
index 00000000000..bb44c77ce37
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/packaged_task.cpp
@@ -0,0 +1,25 @@
+//
+// packaged_task.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/packaged_task.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "packaged_task",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/placeholders.cpp b/3rdparty/asio/src/tests/unit/placeholders.cpp
new file mode 100644
index 00000000000..54cf62ffb41
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/placeholders.cpp
@@ -0,0 +1,25 @@
+//
+// placeholders.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/placeholders.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "placeholders",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/.gitignore b/3rdparty/asio/src/tests/unit/posix/.gitignore
new file mode 100644
index 00000000000..2de575abb5a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/.gitignore
@@ -0,0 +1,15 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+basic_descriptor
+basic_stream_descriptor
+descriptor
+descriptor_base
+stream_descriptor
+stream_descriptor_service
diff --git a/3rdparty/asio/src/tests/unit/posix/basic_descriptor.cpp b/3rdparty/asio/src/tests/unit/posix/basic_descriptor.cpp
new file mode 100644
index 00000000000..c193c0f4b0b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/basic_descriptor.cpp
@@ -0,0 +1,25 @@
+//
+// basic_descriptor.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/basic_descriptor.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "posix/basic_descriptor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/basic_stream_descriptor.cpp b/3rdparty/asio/src/tests/unit/posix/basic_stream_descriptor.cpp
new file mode 100644
index 00000000000..dd2f31db977
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/basic_stream_descriptor.cpp
@@ -0,0 +1,25 @@
+//
+// basic_stream_descriptor.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/basic_stream_descriptor.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "posix/basic_stream_descriptor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/descriptor.cpp b/3rdparty/asio/src/tests/unit/posix/descriptor.cpp
new file mode 100644
index 00000000000..6a52e019da6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/descriptor.cpp
@@ -0,0 +1,25 @@
+//
+// descriptor.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/descriptor.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "posix/descriptor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/descriptor_base.cpp b/3rdparty/asio/src/tests/unit/posix/descriptor_base.cpp
new file mode 100644
index 00000000000..6dc61f88d5d
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/descriptor_base.cpp
@@ -0,0 +1,25 @@
+//
+// descriptor_base.cpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/descriptor_base.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "posix/descriptor_base",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/stream_descriptor.cpp b/3rdparty/asio/src/tests/unit/posix/stream_descriptor.cpp
new file mode 100644
index 00000000000..165db89596f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/stream_descriptor.cpp
@@ -0,0 +1,185 @@
+//
+// stream_descriptor.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/stream_descriptor.hpp"
+
+#include "asio/io_context.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// posix_stream_descriptor_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// posix::stream_descriptor compile and link correctly. Runtime failures are
+// ignored.
+
+namespace posix_stream_descriptor_compile {
+
+void wait_handler(const asio::error_code&)
+{
+}
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+ using namespace asio;
+ namespace posix = asio::posix;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ posix::descriptor_base::bytes_readable io_control_command;
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_stream_descriptor constructors.
+
+ posix::stream_descriptor descriptor1(ioc);
+ int native_descriptor1 = -1;
+ posix::stream_descriptor descriptor2(ioc, native_descriptor1);
+
+#if defined(ASIO_HAS_MOVE)
+ posix::stream_descriptor descriptor3(std::move(descriptor2));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_stream_descriptor operators.
+
+#if defined(ASIO_HAS_MOVE)
+ descriptor1 = posix::stream_descriptor(ioc);
+ descriptor1 = std::move(descriptor2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = descriptor1.get_io_context();
+ (void)ioc_ref;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ posix::stream_descriptor::executor_type ex = descriptor1.get_executor();
+ (void)ex;
+
+ // basic_descriptor functions.
+
+ posix::stream_descriptor::lowest_layer_type& lowest_layer
+ = descriptor1.lowest_layer();
+ (void)lowest_layer;
+
+ const posix::stream_descriptor& descriptor4 = descriptor1;
+ const posix::stream_descriptor::lowest_layer_type& lowest_layer2
+ = descriptor4.lowest_layer();
+ (void)lowest_layer2;
+
+ int native_descriptor2 = -1;
+ descriptor1.assign(native_descriptor2);
+
+ bool is_open = descriptor1.is_open();
+ (void)is_open;
+
+ descriptor1.close();
+ descriptor1.close(ec);
+
+ posix::stream_descriptor::native_handle_type native_descriptor3
+ = descriptor1.native_handle();
+ (void)native_descriptor3;
+
+ posix::stream_descriptor::native_handle_type native_descriptor4
+ = descriptor1.release();
+ (void)native_descriptor4;
+
+ descriptor1.cancel();
+ descriptor1.cancel(ec);
+
+ descriptor1.io_control(io_control_command);
+ descriptor1.io_control(io_control_command, ec);
+
+ bool non_blocking1 = descriptor1.non_blocking();
+ (void)non_blocking1;
+ descriptor1.non_blocking(true);
+ descriptor1.non_blocking(false, ec);
+
+ bool non_blocking2 = descriptor1.native_non_blocking();
+ (void)non_blocking2;
+ descriptor1.native_non_blocking(true);
+ descriptor1.native_non_blocking(false, ec);
+
+ descriptor1.wait(posix::descriptor_base::wait_read);
+ descriptor1.wait(posix::descriptor_base::wait_write, ec);
+
+ descriptor1.async_wait(posix::descriptor_base::wait_read, &wait_handler);
+ int i1 = descriptor1.async_wait(posix::descriptor_base::wait_write, lazy);
+ (void)i1;
+
+ // basic_stream_descriptor functions.
+
+ descriptor1.write_some(buffer(mutable_char_buffer));
+ descriptor1.write_some(buffer(const_char_buffer));
+ descriptor1.write_some(null_buffers());
+ descriptor1.write_some(buffer(mutable_char_buffer), ec);
+ descriptor1.write_some(buffer(const_char_buffer), ec);
+ descriptor1.write_some(null_buffers(), ec);
+
+ descriptor1.async_write_some(buffer(mutable_char_buffer),
+ write_some_handler);
+ descriptor1.async_write_some(buffer(const_char_buffer),
+ write_some_handler);
+ descriptor1.async_write_some(null_buffers(),
+ write_some_handler);
+ int i2 = descriptor1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i2;
+ int i3 = descriptor1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i3;
+ int i4 = descriptor1.async_write_some(null_buffers(), lazy);
+ (void)i4;
+
+ descriptor1.read_some(buffer(mutable_char_buffer));
+ descriptor1.read_some(buffer(mutable_char_buffer), ec);
+ descriptor1.read_some(null_buffers(), ec);
+
+ descriptor1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+ descriptor1.async_read_some(null_buffers(), read_some_handler);
+ int i5 = descriptor1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i5;
+ int i6 = descriptor1.async_read_some(null_buffers(), lazy);
+ (void)i6;
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+}
+
+} // namespace posix_stream_descriptor_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "posix/stream_descriptor",
+ ASIO_TEST_CASE(posix_stream_descriptor_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/posix/stream_descriptor_service.cpp b/3rdparty/asio/src/tests/unit/posix/stream_descriptor_service.cpp
new file mode 100644
index 00000000000..be2e60e7ca3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/posix/stream_descriptor_service.cpp
@@ -0,0 +1,25 @@
+//
+// stream_descriptor_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/posix/stream_descriptor_service.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "posix/stream_descriptor_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/post.cpp b/3rdparty/asio/src/tests/unit/post.cpp
new file mode 100644
index 00000000000..caf8ad53f3a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/post.cpp
@@ -0,0 +1,25 @@
+//
+// post.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/post.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "post",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/raw_socket_service.cpp b/3rdparty/asio/src/tests/unit/raw_socket_service.cpp
new file mode 100644
index 00000000000..c7b736f852e
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/raw_socket_service.cpp
@@ -0,0 +1,25 @@
+//
+// raw_socket_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/raw_socket_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "raw_socket_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/read.cpp b/3rdparty/asio/src/tests/unit/read.cpp
new file mode 100644
index 00000000000..077c9223667
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/read.cpp
@@ -0,0 +1,3927 @@
+//
+// read.cpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/read.hpp"
+
+#include <cstring>
+#include <vector>
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "asio/post.hpp"
+#include "asio/streambuf.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+#include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_stream
+{
+public:
+ typedef asio::io_context::executor_type executor_type;
+
+ test_stream(asio::io_context& io_context)
+ : io_context_(io_context),
+ length_(0),
+ position_(0),
+ next_read_length_(0)
+ {
+ }
+
+ executor_type get_executor() ASIO_NOEXCEPT
+ {
+ return io_context_.get_executor();
+ }
+
+ void reset(const void* data, size_t length)
+ {
+ ASIO_CHECK(length <= max_length);
+
+ memcpy(data_, data, length);
+ length_ = length;
+ position_ = 0;
+ next_read_length_ = length;
+ }
+
+ void next_read_length(size_t length)
+ {
+ next_read_length_ = length;
+ }
+
+ template <typename Iterator>
+ bool check_buffers(Iterator begin, Iterator end, size_t length)
+ {
+ if (length != position_)
+ return false;
+
+ Iterator iter = begin;
+ size_t checked_length = 0;
+ for (; iter != end && checked_length < length; ++iter)
+ {
+ size_t buffer_length = asio::buffer_size(*iter);
+ if (buffer_length > length - checked_length)
+ buffer_length = length - checked_length;
+ if (memcmp(data_ + checked_length, iter->data(), buffer_length) != 0)
+ return false;
+ checked_length += buffer_length;
+ }
+
+ return true;
+ }
+
+ template <typename Const_Buffers>
+ bool check_buffers(const Const_Buffers& buffers, size_t length)
+ {
+ return check_buffers(asio::buffer_sequence_begin(buffers),
+ asio::buffer_sequence_end(buffers), length);
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some(const Mutable_Buffers& buffers)
+ {
+ size_t n = asio::buffer_copy(buffers,
+ asio::buffer(data_, length_) + position_,
+ next_read_length_);
+ position_ += n;
+ return n;
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some(const Mutable_Buffers& buffers,
+ asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return read_some(buffers);
+ }
+
+ template <typename Mutable_Buffers, typename Handler>
+ void async_read_some(const Mutable_Buffers& buffers, Handler handler)
+ {
+ size_t bytes_transferred = read_some(buffers);
+ asio::post(get_executor(),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(Handler)(handler),
+ asio::error_code(), bytes_transferred));
+ }
+
+private:
+ asio::io_context& io_context_;
+ enum { max_length = 8192 };
+ char data_[max_length];
+ size_t length_;
+ size_t position_;
+ size_t next_read_length_;
+};
+
+static const char read_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void test_2_arg_zero_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::mutable_buffer> buffers;
+
+ size_t bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test_2_arg_mutable_buffer_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_2_arg_vector_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_2_arg_streambuf_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = asio::read(s, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+}
+
+void test_3_arg_nothrow_zero_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::mutable_buffer> buffers;
+
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == 0);
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_mutable_buffer_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_vector_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_streambuf_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+bool old_style_transfer_all(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec;
+}
+
+size_t short_transfer(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec ? 0 : 3;
+}
+
+void test_3_arg_mutable_buffer_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_3_arg_vector_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_3_arg_streambuf_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = asio::read(s, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+}
+
+void test_4_arg_mutable_buffer_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_vector_buffers_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_streambuf_read()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ asio::error_code error;
+ size_t bytes_transferred = asio::read(s, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(sb.data(), 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read(s, sb, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read(s, sb, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void async_read_handler(const asio::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!e);
+ ASIO_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_3_arg_mutable_buffer_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_3_arg_boost_array_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ boost::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_3_arg_std_array_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_3_arg_vector_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_3_arg_streambuf_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bool called = false;
+ asio::async_read(s, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ int i = asio::async_read(s, sb, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+}
+
+void test_4_arg_mutable_buffer_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_4_arg_boost_array_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ boost::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_4_arg_std_array_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_4_arg_vector_buffers_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read(s, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read(s, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(read_data)));
+}
+
+void test_4_arg_streambuf_async_read()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bool called = false;
+ asio::async_read(s, sb, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read(s, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ int i = asio::async_read(s, sb,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
+}
+
+ASIO_TEST_SUITE
+(
+ "read",
+ ASIO_TEST_CASE(test_2_arg_zero_buffers_read)
+ ASIO_TEST_CASE(test_2_arg_mutable_buffer_read)
+ ASIO_TEST_CASE(test_2_arg_vector_buffers_read)
+ ASIO_TEST_CASE(test_2_arg_streambuf_read)
+ ASIO_TEST_CASE(test_3_arg_nothrow_zero_buffers_read)
+ ASIO_TEST_CASE(test_3_arg_nothrow_mutable_buffer_read)
+ ASIO_TEST_CASE(test_3_arg_nothrow_vector_buffers_read)
+ ASIO_TEST_CASE(test_3_arg_nothrow_streambuf_read)
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_read)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_read)
+ ASIO_TEST_CASE(test_3_arg_streambuf_read)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_read)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_read)
+ ASIO_TEST_CASE(test_4_arg_streambuf_read)
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_async_read)
+ ASIO_TEST_CASE(test_3_arg_boost_array_buffers_async_read)
+ ASIO_TEST_CASE(test_3_arg_std_array_buffers_async_read)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_async_read)
+ ASIO_TEST_CASE(test_3_arg_streambuf_async_read)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_async_read)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_async_read)
+ ASIO_TEST_CASE(test_4_arg_boost_array_buffers_async_read)
+ ASIO_TEST_CASE(test_4_arg_std_array_buffers_async_read)
+ ASIO_TEST_CASE(test_4_arg_streambuf_async_read)
+)
diff --git a/3rdparty/asio/src/tests/unit/read_at.cpp b/3rdparty/asio/src/tests/unit/read_at.cpp
new file mode 100644
index 00000000000..5b2f5ebace3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/read_at.cpp
@@ -0,0 +1,7493 @@
+//
+// read_at.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/read_at.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "asio/post.hpp"
+#include "asio/streambuf.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+#include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_random_access_device
+{
+public:
+ typedef asio::io_context::executor_type executor_type;
+
+ test_random_access_device(asio::io_context& io_context)
+ : io_context_(io_context),
+ length_(0),
+ next_read_length_(0)
+ {
+ }
+
+ executor_type get_executor() ASIO_NOEXCEPT
+ {
+ return io_context_.get_executor();
+ }
+
+ void reset(const void* data, size_t length)
+ {
+ ASIO_CHECK(length <= max_length);
+
+ length_ = 0;
+ while (length_ + length < max_length)
+ {
+ memcpy(data_ + length_, data, length);
+ length_ += length;
+ }
+
+ next_read_length_ = length;
+ }
+
+ void next_read_length(size_t length)
+ {
+ next_read_length_ = length;
+ }
+
+ template <typename Iterator>
+ bool check_buffers(asio::uint64_t offset,
+ Iterator begin, Iterator end, size_t length)
+ {
+ if (offset + length > max_length)
+ return false;
+
+ Iterator iter = begin;
+ size_t checked_length = 0;
+ for (; iter != end && checked_length < length; ++iter)
+ {
+ size_t buffer_length = asio::buffer_size(*iter);
+ if (buffer_length > length - checked_length)
+ buffer_length = length - checked_length;
+ if (memcmp(data_ + offset + checked_length,
+ iter->data(), buffer_length) != 0)
+ return false;
+ checked_length += buffer_length;
+ }
+
+ return true;
+ }
+
+ template <typename Const_Buffers>
+ bool check_buffers(asio::uint64_t offset,
+ const Const_Buffers& buffers, size_t length)
+ {
+ return check_buffers(offset, asio::buffer_sequence_begin(buffers),
+ asio::buffer_sequence_end(buffers), length);
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some_at(asio::uint64_t offset,
+ const Mutable_Buffers& buffers)
+ {
+ return asio::buffer_copy(buffers,
+ asio::buffer(data_, length_) + offset,
+ next_read_length_);
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some_at(asio::uint64_t offset,
+ const Mutable_Buffers& buffers, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return read_some_at(offset, buffers);
+ }
+
+ template <typename Mutable_Buffers, typename Handler>
+ void async_read_some_at(asio::uint64_t offset,
+ const Mutable_Buffers& buffers, Handler handler)
+ {
+ size_t bytes_transferred = read_some_at(offset, buffers);
+ asio::post(get_executor(),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(Handler)(handler),
+ asio::error_code(), bytes_transferred));
+ }
+
+private:
+ asio::io_context& io_context_;
+ enum { max_length = 8192 };
+ char data_[max_length];
+ size_t length_;
+ size_t next_read_length_;
+};
+
+static const char read_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void test_3_arg_mutable_buffer_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_3_arg_vector_buffers_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_3_arg_streambuf_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = asio::read_at(s, 0, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+void test_4_arg_nothrow_mutable_buffer_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_nothrow_vector_buffers_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_nothrow_streambuf_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+bool old_style_transfer_all(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec;
+}
+
+size_t short_transfer(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec ? 0 : 3;
+}
+
+void test_4_arg_mutable_buffer_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_vector_buffers_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_streambuf_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+void test_5_arg_mutable_buffer_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_5_arg_vector_buffers_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_5_arg_streambuf_read_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ asio::error_code error;
+ size_t bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 50));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 0, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 0, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = asio::error_code();
+ bytes_transferred = asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(read_data));
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ ASIO_CHECK(!error);
+}
+
+void async_read_handler(const asio::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!e);
+ ASIO_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_4_arg_mutable_buffer_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_boost_array_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ boost::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_4_arg_std_array_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_4_arg_vector_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_streambuf_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bool called = false;
+ asio::async_read_at(s, 0, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ int i = asio::async_read_at(s, 1234, sb,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+void test_5_arg_mutable_buffer_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ asio::mutable_buffer buffers
+ = asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_5_arg_boost_array_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ boost::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_5_arg_std_array_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::array<asio::mutable_buffer, 2> buffers = { {
+ asio::buffer(read_buf, 32),
+ asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_5_arg_vector_buffers_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ char read_buf[sizeof(read_data)];
+ std::vector<asio::mutable_buffer> buffers;
+ buffers.push_back(asio::buffer(read_buf, 32));
+ buffers.push_back(asio::buffer(read_buf) + 32);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ asio::async_read_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ int i = asio::async_read_at(s, 1234, buffers,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_5_arg_streambuf_async_read_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bool called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 50);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_read_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 1);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_read_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 10);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_read_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == 42);
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 0, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ asio::async_read_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_read_handler,
+ _1, _2, sizeof(read_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(sb.size() == sizeof(read_data));
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ int i = asio::async_read_at(s, 1234, sb,
+ short_transfer, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+ASIO_TEST_SUITE
+(
+ "read_at",
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_read_at)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_read_at)
+ ASIO_TEST_CASE(test_3_arg_streambuf_read_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_mutable_buffer_read_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_vector_buffers_read_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_streambuf_read_at)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_read_at)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_read_at)
+ ASIO_TEST_CASE(test_4_arg_streambuf_read_at)
+ ASIO_TEST_CASE(test_5_arg_mutable_buffer_read_at)
+ ASIO_TEST_CASE(test_5_arg_vector_buffers_read_at)
+ ASIO_TEST_CASE(test_5_arg_streambuf_read_at)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_async_read_at)
+ ASIO_TEST_CASE(test_4_arg_boost_array_buffers_async_read_at)
+ ASIO_TEST_CASE(test_4_arg_std_array_buffers_async_read_at)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_async_read_at)
+ ASIO_TEST_CASE(test_4_arg_streambuf_async_read_at)
+ ASIO_TEST_CASE(test_5_arg_mutable_buffer_async_read_at)
+ ASIO_TEST_CASE(test_5_arg_boost_array_buffers_async_read_at)
+ ASIO_TEST_CASE(test_5_arg_std_array_buffers_async_read_at)
+ ASIO_TEST_CASE(test_5_arg_vector_buffers_async_read_at)
+ ASIO_TEST_CASE(test_5_arg_streambuf_async_read_at)
+)
diff --git a/3rdparty/asio/src/tests/unit/read_until.cpp b/3rdparty/asio/src/tests/unit/read_until.cpp
new file mode 100644
index 00000000000..782ac2f4b6b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/read_until.cpp
@@ -0,0 +1,887 @@
+//
+// read_until.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/read_until.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "asio/post.hpp"
+#include "asio/streambuf.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+class test_stream
+{
+public:
+ typedef asio::io_context::executor_type executor_type;
+
+ test_stream(asio::io_context& io_context)
+ : io_context_(io_context),
+ length_(0),
+ position_(0),
+ next_read_length_(0)
+ {
+ }
+
+ executor_type get_executor() ASIO_NOEXCEPT
+ {
+ return io_context_.get_executor();
+ }
+
+ void reset(const void* data, size_t length)
+ {
+ using namespace std; // For memcpy.
+
+ ASIO_CHECK(length <= max_length);
+
+ memcpy(data_, data, length);
+ length_ = length;
+ position_ = 0;
+ next_read_length_ = length;
+ }
+
+ void next_read_length(size_t length)
+ {
+ next_read_length_ = length;
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some(const Mutable_Buffers& buffers)
+ {
+ size_t n = asio::buffer_copy(buffers,
+ asio::buffer(data_, length_) + position_,
+ next_read_length_);
+ position_ += n;
+ return n;
+ }
+
+ template <typename Mutable_Buffers>
+ size_t read_some(const Mutable_Buffers& buffers,
+ asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return read_some(buffers);
+ }
+
+ template <typename Mutable_Buffers, typename Handler>
+ void async_read_some(const Mutable_Buffers& buffers, Handler handler)
+ {
+ size_t bytes_transferred = read_some(buffers);
+ asio::post(get_executor(),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(Handler)(handler),
+ asio::error_code(), bytes_transferred));
+ }
+
+private:
+ asio::io_context& io_context_;
+ enum { max_length = 8192 };
+ char data_[max_length];
+ size_t length_;
+ size_t position_;
+ size_t next_read_length_;
+};
+
+static const char read_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void test_char_read_until()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ std::size_t length = asio::read_until(s, sb1, 'Z');
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, 'Z');
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, 'Z');
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, 'Z', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, 'Z', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, 'Z', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Z', ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Z', ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Z', ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Y', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Y', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, 'Y', ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+}
+
+void test_string_read_until()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ std::size_t length = asio::read_until(s, sb1, "XYZ");
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, "XYZ");
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, "XYZ");
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, "XYZ", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, "XYZ", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, "XYZ", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "XYZ", ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "XYZ", ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "XYZ", ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "WXY", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "WXY", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, "WXY", ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+}
+
+class match_char
+{
+public:
+ explicit match_char(char c) : c_(c) {}
+
+ template <typename Iterator>
+ std::pair<Iterator, bool> operator()(
+ Iterator begin, Iterator end) const
+ {
+ Iterator i = begin;
+ while (i != end)
+ if (c_ == *i++)
+ return std::make_pair(i, true);
+ return std::make_pair(i, false);
+ }
+
+private:
+ char c_;
+};
+
+namespace asio {
+ template <> struct is_match_condition<match_char>
+ {
+ enum { value = true };
+ };
+} // namespace asio
+
+void test_match_condition_read_until()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ std::size_t length = asio::read_until(s, sb1, match_char('Z'));
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, match_char('Z'));
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, match_char('Z'));
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, match_char('Z'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, match_char('Z'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb1.consume(sb1.size());
+ length = asio::read_until(s, sb1, match_char('Z'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Z'), ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Z'), ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Z'), ec);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Y'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Y'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb2.consume(sb2.size());
+ length = asio::read_until(s, sb2, match_char('Y'), ec);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+}
+
+void async_read_handler(
+ const asio::error_code& err, asio::error_code* err_out,
+ std::size_t bytes_transferred, std::size_t* bytes_out, bool* called)
+{
+ *err_out = err;
+ *bytes_out = bytes_transferred;
+ *called = true;
+}
+
+void test_char_async_read_until()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+ std::size_t length;
+ bool called;
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Z',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Y',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Y',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, 'Y',
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ int i = asio::async_read_until(s, sb2, 'Y',
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+}
+
+void test_string_async_read_until()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+ std::size_t length;
+ bool called;
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "XYZ",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "WXY",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "WXY",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, "WXY",
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ int i = asio::async_read_until(s, sb2, "WXY",
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+}
+
+void test_match_condition_async_read_until()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb1;
+ asio::streambuf sb2(25);
+ asio::error_code ec;
+ std::size_t length;
+ bool called;
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb1.consume(sb1.size());
+ asio::async_read_until(s, sb1, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 26);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Z'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == asio::error::not_found);
+ ASIO_CHECK(length == 0);
+
+ s.reset(read_data, sizeof(read_data));
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Y'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Y'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ ec = asio::error_code();
+ length = 0;
+ called = false;
+ sb2.consume(sb2.size());
+ asio::async_read_until(s, sb2, match_char('Y'),
+ bindns::bind(async_read_handler, _1, &ec,
+ _2, &length, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(!ec);
+ ASIO_CHECK(length == 25);
+
+ s.reset(read_data, sizeof(read_data));
+ sb2.consume(sb2.size());
+ int i = asio::async_read_until(s, sb2, match_char('Y'),
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+}
+
+ASIO_TEST_SUITE
+(
+ "read_until",
+ ASIO_TEST_CASE(test_char_read_until)
+ ASIO_TEST_CASE(test_string_read_until)
+ ASIO_TEST_CASE(test_match_condition_read_until)
+ ASIO_TEST_CASE(test_char_async_read_until)
+ ASIO_TEST_CASE(test_string_async_read_until)
+ ASIO_TEST_CASE(test_match_condition_async_read_until)
+)
diff --git a/3rdparty/asio/src/tests/unit/seq_packet_socket_service.cpp b/3rdparty/asio/src/tests/unit/seq_packet_socket_service.cpp
new file mode 100644
index 00000000000..fc2d73c7ae9
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/seq_packet_socket_service.cpp
@@ -0,0 +1,25 @@
+//
+// seq_packet_socket_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/seq_packet_socket_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "seq_packet_socket_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/serial_port.cpp b/3rdparty/asio/src/tests/unit/serial_port.cpp
new file mode 100644
index 00000000000..ff6e2dc261a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/serial_port.cpp
@@ -0,0 +1,171 @@
+//
+// serial_port.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/serial_port.hpp"
+
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// serial_port_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// serial_port compile and link correctly. Runtime failures are ignored.
+
+namespace serial_port_compile {
+
+struct write_some_handler
+{
+ write_some_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ write_some_handler(write_some_handler&&) {}
+private:
+ write_some_handler(const write_some_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+struct read_some_handler
+{
+ read_some_handler() {}
+ void operator()(const asio::error_code&, std::size_t) {}
+#if defined(ASIO_HAS_MOVE)
+ read_some_handler(read_some_handler&&) {}
+private:
+ read_some_handler(const read_some_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void test()
+{
+#if defined(ASIO_HAS_SERIAL_PORT)
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ serial_port::baud_rate serial_port_option;
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_serial_port constructors.
+
+ serial_port port1(ioc);
+ serial_port port2(ioc, "null");
+ serial_port::native_handle_type native_port1 = port1.native_handle();
+ serial_port port3(ioc, native_port1);
+
+#if defined(ASIO_HAS_MOVE)
+ serial_port port4(std::move(port3));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_serial_port operators.
+
+#if defined(ASIO_HAS_MOVE)
+ port1 = serial_port(ioc);
+ port1 = std::move(port2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+ serial_port::executor_type ex = port1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = port1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = port1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_serial_port functions.
+
+ serial_port::lowest_layer_type& lowest_layer = port1.lowest_layer();
+ (void)lowest_layer;
+
+ const serial_port& port5 = port1;
+ const serial_port::lowest_layer_type& lowest_layer2 = port5.lowest_layer();
+ (void)lowest_layer2;
+
+ port1.open("null");
+ port1.open("null", ec);
+
+ serial_port::native_handle_type native_port2 = port1.native_handle();
+ port1.assign(native_port2);
+ serial_port::native_handle_type native_port3 = port1.native_handle();
+ port1.assign(native_port3, ec);
+
+ bool is_open = port1.is_open();
+ (void)is_open;
+
+ port1.close();
+ port1.close(ec);
+
+ serial_port::native_handle_type native_port4 = port1.native_handle();
+ (void)native_port4;
+
+ port1.cancel();
+ port1.cancel(ec);
+
+ port1.set_option(serial_port_option);
+ port1.set_option(serial_port_option, ec);
+
+ port1.get_option(serial_port_option);
+ port1.get_option(serial_port_option, ec);
+
+ port1.send_break();
+ port1.send_break(ec);
+
+ port1.write_some(buffer(mutable_char_buffer));
+ port1.write_some(buffer(const_char_buffer));
+ port1.write_some(buffer(mutable_char_buffer), ec);
+ port1.write_some(buffer(const_char_buffer), ec);
+
+ port1.async_write_some(buffer(mutable_char_buffer), write_some_handler());
+ port1.async_write_some(buffer(const_char_buffer), write_some_handler());
+ int i1 = port1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = port1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i2;
+
+ port1.read_some(buffer(mutable_char_buffer));
+ port1.read_some(buffer(mutable_char_buffer), ec);
+
+ port1.async_read_some(buffer(mutable_char_buffer), read_some_handler());
+ int i3 = port1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i3;
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_SERIAL_PORT)
+}
+
+} // namespace serial_port_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "serial_port",
+ ASIO_TEST_CASE(serial_port_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/serial_port_base.cpp b/3rdparty/asio/src/tests/unit/serial_port_base.cpp
new file mode 100644
index 00000000000..d05e7bbaafe
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/serial_port_base.cpp
@@ -0,0 +1,99 @@
+//
+// serial_port_base.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/serial_port_base.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/serial_port.hpp"
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// serial_port_base_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Verify that all options and and their accessors compile. Runtime failures are
+// ignored.
+
+namespace serial_port_base_compile {
+
+void test()
+{
+#if defined(ASIO_HAS_SERIAL_PORT)
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ serial_port port(ioc);
+
+ // baud_rate class.
+
+ serial_port_base::baud_rate baud_rate1(9600);
+ port.set_option(baud_rate1);
+ serial_port_base::baud_rate baud_rate2;
+ port.get_option(baud_rate2);
+ (void)static_cast<unsigned int>(baud_rate2.value());
+
+ // flow_control class.
+
+ serial_port_base::flow_control flow_control1(
+ serial_port_base::flow_control::none);
+ port.set_option(flow_control1);
+ serial_port_base::flow_control flow_control2;
+ port.get_option(flow_control2);
+ (void)static_cast<serial_port_base::flow_control::type>(
+ flow_control2.value());
+
+ // parity class.
+
+ serial_port_base::parity parity1(serial_port_base::parity::none);
+ port.set_option(parity1);
+ serial_port_base::parity parity2;
+ port.get_option(parity2);
+ (void)static_cast<serial_port_base::parity::type>(parity2.value());
+
+ // stop_bits class.
+
+ serial_port_base::stop_bits stop_bits1(serial_port_base::stop_bits::one);
+ port.set_option(stop_bits1);
+ serial_port_base::stop_bits stop_bits2;
+ port.get_option(stop_bits2);
+ (void)static_cast<serial_port_base::stop_bits::type>(stop_bits2.value());
+
+ // character_size class.
+
+ serial_port_base::character_size character_size1(8);
+ port.set_option(character_size1);
+ serial_port_base::character_size character_size2;
+ port.get_option(character_size2);
+ (void)static_cast<unsigned int>(character_size2.value());
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_SERIAL_PORT)
+}
+
+} // namespace serial_port_base_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "serial_port_base",
+ ASIO_TEST_CASE(serial_port_base_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/serial_port_service.cpp b/3rdparty/asio/src/tests/unit/serial_port_service.cpp
new file mode 100644
index 00000000000..c0c596194e7
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/serial_port_service.cpp
@@ -0,0 +1,26 @@
+//
+// serial_port_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/serial_port_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "serial_port_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/signal_set.cpp b/3rdparty/asio/src/tests/unit/signal_set.cpp
new file mode 100644
index 00000000000..7118bb96ac0
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/signal_set.cpp
@@ -0,0 +1,97 @@
+//
+// signal_set.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/signal_set.hpp"
+
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// signal_set_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// signal_set compile and link correctly. Runtime failures are ignored.
+
+namespace signal_set_compile {
+
+void signal_handler(const asio::error_code&, int)
+{
+}
+
+void test()
+{
+ using namespace asio;
+
+ try
+ {
+ io_context ioc;
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_signal_set constructors.
+
+ signal_set set1(ioc);
+ signal_set set2(ioc, 1);
+ signal_set set3(ioc, 1, 2);
+ signal_set set4(ioc, 1, 2, 3);
+
+ // basic_io_object functions.
+
+ signal_set::executor_type ex = set1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = set1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = set1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // basic_signal_set functions.
+
+ set1.add(1);
+ set1.add(1, ec);
+
+ set1.remove(1);
+ set1.remove(1, ec);
+
+ set1.clear();
+ set1.clear(ec);
+
+ set1.cancel();
+ set1.cancel(ec);
+
+ set1.async_wait(&signal_handler);
+ int i = set1.async_wait(lazy);
+ (void)i;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace signal_set_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "signal_set",
+ ASIO_TEST_CASE(signal_set_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/signal_set_service.cpp b/3rdparty/asio/src/tests/unit/signal_set_service.cpp
new file mode 100644
index 00000000000..1dd2a2c651f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/signal_set_service.cpp
@@ -0,0 +1,25 @@
+//
+// signal_set_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/signal_set_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "signal_set_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/socket_acceptor_service.cpp b/3rdparty/asio/src/tests/unit/socket_acceptor_service.cpp
new file mode 100644
index 00000000000..772218631a6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/socket_acceptor_service.cpp
@@ -0,0 +1,25 @@
+//
+// socket_acceptor_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/socket_acceptor_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "socket_acceptor_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/socket_base.cpp b/3rdparty/asio/src/tests/unit/socket_base.cpp
new file mode 100644
index 00000000000..f7170ace0e9
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/socket_base.cpp
@@ -0,0 +1,639 @@
+//
+// socket_base.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/socket_base.hpp"
+
+#include "asio/io_context.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/ip/udp.hpp"
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// socket_base_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all nested classes, enums and constants in
+// socket_base compile and link correctly. Runtime failures are ignored.
+
+namespace socket_base_compile {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ ip::tcp::socket sock(ioc);
+ char buf[1024];
+
+ // shutdown_type enumeration.
+
+ sock.shutdown(socket_base::shutdown_receive);
+ sock.shutdown(socket_base::shutdown_send);
+ sock.shutdown(socket_base::shutdown_both);
+
+ // message_flags constants.
+
+ sock.receive(buffer(buf), socket_base::message_peek);
+ sock.receive(buffer(buf), socket_base::message_out_of_band);
+ sock.send(buffer(buf), socket_base::message_do_not_route);
+
+ // broadcast class.
+
+ socket_base::broadcast broadcast1(true);
+ sock.set_option(broadcast1);
+ socket_base::broadcast broadcast2;
+ sock.get_option(broadcast2);
+ broadcast1 = true;
+ (void)static_cast<bool>(broadcast1);
+ (void)static_cast<bool>(!broadcast1);
+ (void)static_cast<bool>(broadcast1.value());
+
+ // debug class.
+
+ socket_base::debug debug1(true);
+ sock.set_option(debug1);
+ socket_base::debug debug2;
+ sock.get_option(debug2);
+ debug1 = true;
+ (void)static_cast<bool>(debug1);
+ (void)static_cast<bool>(!debug1);
+ (void)static_cast<bool>(debug1.value());
+
+ // do_not_route class.
+
+ socket_base::do_not_route do_not_route1(true);
+ sock.set_option(do_not_route1);
+ socket_base::do_not_route do_not_route2;
+ sock.get_option(do_not_route2);
+ do_not_route1 = true;
+ (void)static_cast<bool>(do_not_route1);
+ (void)static_cast<bool>(!do_not_route1);
+ (void)static_cast<bool>(do_not_route1.value());
+
+ // keep_alive class.
+
+ socket_base::keep_alive keep_alive1(true);
+ sock.set_option(keep_alive1);
+ socket_base::keep_alive keep_alive2;
+ sock.get_option(keep_alive2);
+ keep_alive1 = true;
+ (void)static_cast<bool>(keep_alive1);
+ (void)static_cast<bool>(!keep_alive1);
+ (void)static_cast<bool>(keep_alive1.value());
+
+ // send_buffer_size class.
+
+ socket_base::send_buffer_size send_buffer_size1(1024);
+ sock.set_option(send_buffer_size1);
+ socket_base::send_buffer_size send_buffer_size2;
+ sock.get_option(send_buffer_size2);
+ send_buffer_size1 = 1;
+ (void)static_cast<int>(send_buffer_size1.value());
+
+ // send_low_watermark class.
+
+ socket_base::send_low_watermark send_low_watermark1(128);
+ sock.set_option(send_low_watermark1);
+ socket_base::send_low_watermark send_low_watermark2;
+ sock.get_option(send_low_watermark2);
+ send_low_watermark1 = 1;
+ (void)static_cast<int>(send_low_watermark1.value());
+
+ // receive_buffer_size class.
+
+ socket_base::receive_buffer_size receive_buffer_size1(1024);
+ sock.set_option(receive_buffer_size1);
+ socket_base::receive_buffer_size receive_buffer_size2;
+ sock.get_option(receive_buffer_size2);
+ receive_buffer_size1 = 1;
+ (void)static_cast<int>(receive_buffer_size1.value());
+
+ // receive_low_watermark class.
+
+ socket_base::receive_low_watermark receive_low_watermark1(128);
+ sock.set_option(receive_low_watermark1);
+ socket_base::receive_low_watermark receive_low_watermark2;
+ sock.get_option(receive_low_watermark2);
+ receive_low_watermark1 = 1;
+ (void)static_cast<int>(receive_low_watermark1.value());
+
+ // reuse_address class.
+
+ socket_base::reuse_address reuse_address1(true);
+ sock.set_option(reuse_address1);
+ socket_base::reuse_address reuse_address2;
+ sock.get_option(reuse_address2);
+ reuse_address1 = true;
+ (void)static_cast<bool>(reuse_address1);
+ (void)static_cast<bool>(!reuse_address1);
+ (void)static_cast<bool>(reuse_address1.value());
+
+ // linger class.
+
+ socket_base::linger linger1(true, 30);
+ sock.set_option(linger1);
+ socket_base::linger linger2;
+ sock.get_option(linger2);
+ linger1.enabled(true);
+ (void)static_cast<bool>(linger1.enabled());
+ linger1.timeout(1);
+ (void)static_cast<int>(linger1.timeout());
+
+ // enable_connection_aborted class.
+
+ socket_base::enable_connection_aborted enable_connection_aborted1(true);
+ sock.set_option(enable_connection_aborted1);
+ socket_base::enable_connection_aborted enable_connection_aborted2;
+ sock.get_option(enable_connection_aborted2);
+ enable_connection_aborted1 = true;
+ (void)static_cast<bool>(enable_connection_aborted1);
+ (void)static_cast<bool>(!enable_connection_aborted1);
+ (void)static_cast<bool>(enable_connection_aborted1.value());
+
+ // bytes_readable class.
+
+ socket_base::bytes_readable bytes_readable;
+ sock.io_control(bytes_readable);
+ std::size_t bytes = bytes_readable.get();
+ (void)bytes;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace socket_base_compile
+
+//------------------------------------------------------------------------------
+
+// socket_base_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the socket options and I/O
+// control commands defined in socket_base.
+
+namespace socket_base_runtime {
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ io_context ioc;
+ ip::udp::socket udp_sock(ioc, ip::udp::v4());
+ ip::tcp::socket tcp_sock(ioc, ip::tcp::v4());
+ ip::tcp::acceptor tcp_acceptor(ioc, ip::tcp::v4());
+ asio::error_code ec;
+
+ // broadcast class.
+
+ socket_base::broadcast broadcast1(true);
+ ASIO_CHECK(broadcast1.value());
+ ASIO_CHECK(static_cast<bool>(broadcast1));
+ ASIO_CHECK(!!broadcast1);
+ udp_sock.set_option(broadcast1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::broadcast broadcast2;
+ udp_sock.get_option(broadcast2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(broadcast2.value());
+ ASIO_CHECK(static_cast<bool>(broadcast2));
+ ASIO_CHECK(!!broadcast2);
+
+ socket_base::broadcast broadcast3(false);
+ ASIO_CHECK(!broadcast3.value());
+ ASIO_CHECK(!static_cast<bool>(broadcast3));
+ ASIO_CHECK(!broadcast3);
+ udp_sock.set_option(broadcast3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::broadcast broadcast4;
+ udp_sock.get_option(broadcast4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!broadcast4.value());
+ ASIO_CHECK(!static_cast<bool>(broadcast4));
+ ASIO_CHECK(!broadcast4);
+
+ // debug class.
+
+ socket_base::debug debug1(true);
+ ASIO_CHECK(debug1.value());
+ ASIO_CHECK(static_cast<bool>(debug1));
+ ASIO_CHECK(!!debug1);
+ udp_sock.set_option(debug1, ec);
+#if defined(__linux__)
+ // On Linux, only root can set SO_DEBUG.
+ bool not_root = (ec == asio::error::access_denied);
+ ASIO_CHECK(!ec || not_root);
+ ASIO_WARN_MESSAGE(!ec, "Must be root to set debug socket option");
+#else // defined(__linux__)
+# if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+# else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+# endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+#endif // defined(__linux__)
+
+ socket_base::debug debug2;
+ udp_sock.get_option(debug2, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+# if defined(__linux__)
+ ASIO_CHECK(debug2.value() || not_root);
+ ASIO_CHECK(static_cast<bool>(debug2) || not_root);
+ ASIO_CHECK(!!debug2 || not_root);
+# else // defined(__linux__)
+ ASIO_CHECK(debug2.value());
+ ASIO_CHECK(static_cast<bool>(debug2));
+ ASIO_CHECK(!!debug2);
+# endif // defined(__linux__)
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::debug debug3(false);
+ ASIO_CHECK(!debug3.value());
+ ASIO_CHECK(!static_cast<bool>(debug3));
+ ASIO_CHECK(!debug3);
+ udp_sock.set_option(debug3, ec);
+#if defined(__linux__)
+ ASIO_CHECK(!ec || not_root);
+#else // defined(__linux__)
+# if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+# else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+# endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+#endif // defined(__linux__)
+
+ socket_base::debug debug4;
+ udp_sock.get_option(debug4, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+# if defined(__linux__)
+ ASIO_CHECK(!debug4.value() || not_root);
+ ASIO_CHECK(!static_cast<bool>(debug4) || not_root);
+ ASIO_CHECK(!debug4 || not_root);
+# else // defined(__linux__)
+ ASIO_CHECK(!debug4.value());
+ ASIO_CHECK(!static_cast<bool>(debug4));
+ ASIO_CHECK(!debug4);
+# endif // defined(__linux__)
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ // do_not_route class.
+
+ socket_base::do_not_route do_not_route1(true);
+ ASIO_CHECK(do_not_route1.value());
+ ASIO_CHECK(static_cast<bool>(do_not_route1));
+ ASIO_CHECK(!!do_not_route1);
+ udp_sock.set_option(do_not_route1, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::do_not_route do_not_route2;
+ udp_sock.get_option(do_not_route2, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(do_not_route2.value());
+ ASIO_CHECK(static_cast<bool>(do_not_route2));
+ ASIO_CHECK(!!do_not_route2);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::do_not_route do_not_route3(false);
+ ASIO_CHECK(!do_not_route3.value());
+ ASIO_CHECK(!static_cast<bool>(do_not_route3));
+ ASIO_CHECK(!do_not_route3);
+ udp_sock.set_option(do_not_route3, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::do_not_route do_not_route4;
+ udp_sock.get_option(do_not_route4, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!do_not_route4.value());
+ ASIO_CHECK(!static_cast<bool>(do_not_route4));
+ ASIO_CHECK(!do_not_route4);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ // keep_alive class.
+
+ socket_base::keep_alive keep_alive1(true);
+ ASIO_CHECK(keep_alive1.value());
+ ASIO_CHECK(static_cast<bool>(keep_alive1));
+ ASIO_CHECK(!!keep_alive1);
+ tcp_sock.set_option(keep_alive1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::keep_alive keep_alive2;
+ tcp_sock.get_option(keep_alive2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(keep_alive2.value());
+ ASIO_CHECK(static_cast<bool>(keep_alive2));
+ ASIO_CHECK(!!keep_alive2);
+
+ socket_base::keep_alive keep_alive3(false);
+ ASIO_CHECK(!keep_alive3.value());
+ ASIO_CHECK(!static_cast<bool>(keep_alive3));
+ ASIO_CHECK(!keep_alive3);
+ tcp_sock.set_option(keep_alive3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::keep_alive keep_alive4;
+ tcp_sock.get_option(keep_alive4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!keep_alive4.value());
+ ASIO_CHECK(!static_cast<bool>(keep_alive4));
+ ASIO_CHECK(!keep_alive4);
+
+ // send_buffer_size class.
+
+ socket_base::send_buffer_size send_buffer_size1(4096);
+ ASIO_CHECK(send_buffer_size1.value() == 4096);
+ tcp_sock.set_option(send_buffer_size1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::send_buffer_size send_buffer_size2;
+ tcp_sock.get_option(send_buffer_size2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(send_buffer_size2.value() == 4096);
+
+ socket_base::send_buffer_size send_buffer_size3(16384);
+ ASIO_CHECK(send_buffer_size3.value() == 16384);
+ tcp_sock.set_option(send_buffer_size3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::send_buffer_size send_buffer_size4;
+ tcp_sock.get_option(send_buffer_size4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(send_buffer_size4.value() == 16384);
+
+ // send_low_watermark class.
+
+ socket_base::send_low_watermark send_low_watermark1(4096);
+ ASIO_CHECK(send_low_watermark1.value() == 4096);
+ tcp_sock.set_option(send_low_watermark1, ec);
+#if defined(WIN32) || defined(__linux__) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif
+
+ socket_base::send_low_watermark send_low_watermark2;
+ tcp_sock.get_option(send_low_watermark2, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#elif defined(__linux__)
+ ASIO_CHECK(!ec); // Not supported on Linux but can get value.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(send_low_watermark2.value() == 4096);
+#endif
+
+ socket_base::send_low_watermark send_low_watermark3(8192);
+ ASIO_CHECK(send_low_watermark3.value() == 8192);
+ tcp_sock.set_option(send_low_watermark3, ec);
+#if defined(WIN32) || defined(__linux__) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif
+
+ socket_base::send_low_watermark send_low_watermark4;
+ tcp_sock.get_option(send_low_watermark4, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#elif defined(__linux__)
+ ASIO_CHECK(!ec); // Not supported on Linux but can get value.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(send_low_watermark4.value() == 8192);
+#endif
+
+ // receive_buffer_size class.
+
+ socket_base::receive_buffer_size receive_buffer_size1(4096);
+ ASIO_CHECK(receive_buffer_size1.value() == 4096);
+ tcp_sock.set_option(receive_buffer_size1, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::receive_buffer_size receive_buffer_size2;
+ tcp_sock.get_option(receive_buffer_size2, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(receive_buffer_size2.value() == 4096);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::receive_buffer_size receive_buffer_size3(16384);
+ ASIO_CHECK(receive_buffer_size3.value() == 16384);
+ tcp_sock.set_option(receive_buffer_size3, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ // Option is not supported under Windows CE.
+ ASIO_CHECK_MESSAGE(ec == asio::error::no_protocol_option,
+ ec.value() << ", " << ec.message());
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ socket_base::receive_buffer_size receive_buffer_size4;
+ tcp_sock.get_option(receive_buffer_size4, ec);
+#if defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
+#else // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(receive_buffer_size4.value() == 16384);
+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)
+
+ // receive_low_watermark class.
+
+ socket_base::receive_low_watermark receive_low_watermark1(4096);
+ ASIO_CHECK(receive_low_watermark1.value() == 4096);
+ tcp_sock.set_option(receive_low_watermark1, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif
+
+ socket_base::receive_low_watermark receive_low_watermark2;
+ tcp_sock.get_option(receive_low_watermark2, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(receive_low_watermark2.value() == 4096);
+#endif
+
+ socket_base::receive_low_watermark receive_low_watermark3(8192);
+ ASIO_CHECK(receive_low_watermark3.value() == 8192);
+ tcp_sock.set_option(receive_low_watermark3, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+#endif
+
+ socket_base::receive_low_watermark receive_low_watermark4;
+ tcp_sock.get_option(receive_low_watermark4, ec);
+#if defined(WIN32) || defined(__sun)
+ ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
+#else
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(receive_low_watermark4.value() == 8192);
+#endif
+
+ // reuse_address class.
+
+ socket_base::reuse_address reuse_address1(true);
+ ASIO_CHECK(reuse_address1.value());
+ ASIO_CHECK(static_cast<bool>(reuse_address1));
+ ASIO_CHECK(!!reuse_address1);
+ udp_sock.set_option(reuse_address1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::reuse_address reuse_address2;
+ udp_sock.get_option(reuse_address2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(reuse_address2.value());
+ ASIO_CHECK(static_cast<bool>(reuse_address2));
+ ASIO_CHECK(!!reuse_address2);
+
+ socket_base::reuse_address reuse_address3(false);
+ ASIO_CHECK(!reuse_address3.value());
+ ASIO_CHECK(!static_cast<bool>(reuse_address3));
+ ASIO_CHECK(!reuse_address3);
+ udp_sock.set_option(reuse_address3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::reuse_address reuse_address4;
+ udp_sock.get_option(reuse_address4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!reuse_address4.value());
+ ASIO_CHECK(!static_cast<bool>(reuse_address4));
+ ASIO_CHECK(!reuse_address4);
+
+ // linger class.
+
+ socket_base::linger linger1(true, 60);
+ ASIO_CHECK(linger1.enabled());
+ ASIO_CHECK(linger1.timeout() == 60);
+ tcp_sock.set_option(linger1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::linger linger2;
+ tcp_sock.get_option(linger2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(linger2.enabled());
+ ASIO_CHECK(linger2.timeout() == 60);
+
+ socket_base::linger linger3(false, 0);
+ ASIO_CHECK(!linger3.enabled());
+ ASIO_CHECK(linger3.timeout() == 0);
+ tcp_sock.set_option(linger3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::linger linger4;
+ tcp_sock.get_option(linger4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!linger4.enabled());
+
+ // enable_connection_aborted class.
+
+ socket_base::enable_connection_aborted enable_connection_aborted1(true);
+ ASIO_CHECK(enable_connection_aborted1.value());
+ ASIO_CHECK(static_cast<bool>(enable_connection_aborted1));
+ ASIO_CHECK(!!enable_connection_aborted1);
+ tcp_acceptor.set_option(enable_connection_aborted1, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::enable_connection_aborted enable_connection_aborted2;
+ tcp_acceptor.get_option(enable_connection_aborted2, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(enable_connection_aborted2.value());
+ ASIO_CHECK(static_cast<bool>(enable_connection_aborted2));
+ ASIO_CHECK(!!enable_connection_aborted2);
+
+ socket_base::enable_connection_aborted enable_connection_aborted3(false);
+ ASIO_CHECK(!enable_connection_aborted3.value());
+ ASIO_CHECK(!static_cast<bool>(enable_connection_aborted3));
+ ASIO_CHECK(!enable_connection_aborted3);
+ tcp_acceptor.set_option(enable_connection_aborted3, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+
+ socket_base::enable_connection_aborted enable_connection_aborted4;
+ tcp_acceptor.get_option(enable_connection_aborted4, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+ ASIO_CHECK(!enable_connection_aborted4.value());
+ ASIO_CHECK(!static_cast<bool>(enable_connection_aborted4));
+ ASIO_CHECK(!enable_connection_aborted4);
+
+ // bytes_readable class.
+
+ socket_base::bytes_readable bytes_readable;
+ udp_sock.io_control(bytes_readable, ec);
+ ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
+}
+
+} // namespace socket_base_runtime
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "socket_base",
+ ASIO_TEST_CASE(socket_base_compile::test)
+ ASIO_TEST_CASE(socket_base_runtime::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ssl/.gitignore b/3rdparty/asio/src/tests/unit/ssl/.gitignore
new file mode 100644
index 00000000000..5c2ad3eba55
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/.gitignore
@@ -0,0 +1,14 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+context
+context_base
+rfc2818_verification
+stream
+stream_base
diff --git a/3rdparty/asio/src/tests/unit/ssl/context.cpp b/3rdparty/asio/src/tests/unit/ssl/context.cpp
new file mode 100644
index 00000000000..27d63d5a9bc
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/context.cpp
@@ -0,0 +1,25 @@
+//
+// context.cpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ssl/context.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ssl/context",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ssl/context_base.cpp b/3rdparty/asio/src/tests/unit/ssl/context_base.cpp
new file mode 100644
index 00000000000..19ef5740d2f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/context_base.cpp
@@ -0,0 +1,25 @@
+//
+// context_base.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ssl/context_base.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ssl/context_base",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ssl/rfc2818_verification.cpp b/3rdparty/asio/src/tests/unit/ssl/rfc2818_verification.cpp
new file mode 100644
index 00000000000..15e0b5e35c3
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/rfc2818_verification.cpp
@@ -0,0 +1,25 @@
+//
+// rfc2818_verification.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ssl/rfc2818_verification.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ssl/rfc2818_verification",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ssl/stream.cpp b/3rdparty/asio/src/tests/unit/ssl/stream.cpp
new file mode 100644
index 00000000000..542949eb60c
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/stream.cpp
@@ -0,0 +1,199 @@
+//
+// stream.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ssl/stream.hpp"
+
+#include "asio.hpp"
+#include "asio/ssl.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// ssl_stream_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ssl::stream::socket compile and link correctly. Runtime failures are ignored.
+
+namespace ssl_stream_compile {
+
+bool verify_callback(bool, asio::ssl::verify_context&)
+{
+ return false;
+}
+
+void handshake_handler(const asio::error_code&)
+{
+}
+
+void buffered_handshake_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void shutdown_handler(const asio::error_code&)
+{
+}
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+ using namespace asio;
+ namespace ip = asio::ip;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ asio::ssl::context context(asio::ssl::context::sslv23);
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // ssl::stream constructors.
+
+ ssl::stream<ip::tcp::socket> stream1(ioc, context);
+ ip::tcp::socket socket1(ioc, ip::tcp::v4());
+ ssl::stream<ip::tcp::socket&> stream2(socket1, context);
+
+ // basic_io_object functions.
+
+ ssl::stream<ip::tcp::socket>::executor_type ex = stream1.get_executor();
+ (void)ex;
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = stream1.get_io_context();
+ (void)ioc_ref;
+
+ io_context& ioc_ref2 = stream1.get_io_service();
+ (void)ioc_ref2;
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+ // ssl::stream functions.
+
+ SSL* ssl1 = stream1.native_handle();
+ (void)ssl1;
+
+ ssl::stream<ip::tcp::socket>::lowest_layer_type& lowest_layer
+ = stream1.lowest_layer();
+ (void)lowest_layer;
+
+ const ssl::stream<ip::tcp::socket>& stream3 = stream1;
+ const ssl::stream<ip::tcp::socket>::lowest_layer_type& lowest_layer2
+ = stream3.lowest_layer();
+ (void)lowest_layer2;
+
+ stream1.set_verify_mode(ssl::verify_none);
+ stream1.set_verify_mode(ssl::verify_none, ec);
+
+ stream1.set_verify_depth(1);
+ stream1.set_verify_depth(1, ec);
+
+ stream1.set_verify_callback(verify_callback);
+ stream1.set_verify_callback(verify_callback, ec);
+
+ stream1.handshake(ssl::stream_base::client);
+ stream1.handshake(ssl::stream_base::server);
+ stream1.handshake(ssl::stream_base::client, ec);
+ stream1.handshake(ssl::stream_base::server, ec);
+
+ stream1.handshake(ssl::stream_base::client, buffer(mutable_char_buffer));
+ stream1.handshake(ssl::stream_base::server, buffer(mutable_char_buffer));
+ stream1.handshake(ssl::stream_base::client, buffer(const_char_buffer));
+ stream1.handshake(ssl::stream_base::server, buffer(const_char_buffer));
+ stream1.handshake(ssl::stream_base::client,
+ buffer(mutable_char_buffer), ec);
+ stream1.handshake(ssl::stream_base::server,
+ buffer(mutable_char_buffer), ec);
+ stream1.handshake(ssl::stream_base::client,
+ buffer(const_char_buffer), ec);
+ stream1.handshake(ssl::stream_base::server,
+ buffer(const_char_buffer), ec);
+
+ stream1.async_handshake(ssl::stream_base::client, handshake_handler);
+ stream1.async_handshake(ssl::stream_base::server, handshake_handler);
+ int i1 = stream1.async_handshake(ssl::stream_base::client, lazy);
+ (void)i1;
+ int i2 = stream1.async_handshake(ssl::stream_base::server, lazy);
+ (void)i2;
+
+ stream1.async_handshake(ssl::stream_base::client,
+ buffer(mutable_char_buffer), buffered_handshake_handler);
+ stream1.async_handshake(ssl::stream_base::server,
+ buffer(mutable_char_buffer), buffered_handshake_handler);
+ stream1.async_handshake(ssl::stream_base::client,
+ buffer(const_char_buffer), buffered_handshake_handler);
+ stream1.async_handshake(ssl::stream_base::server,
+ buffer(const_char_buffer), buffered_handshake_handler);
+ int i3 = stream1.async_handshake(ssl::stream_base::client,
+ buffer(mutable_char_buffer), lazy);
+ (void)i3;
+ int i4 = stream1.async_handshake(ssl::stream_base::server,
+ buffer(mutable_char_buffer), lazy);
+ (void)i4;
+ int i5 = stream1.async_handshake(ssl::stream_base::client,
+ buffer(const_char_buffer), lazy);
+ (void)i5;
+ int i6 = stream1.async_handshake(ssl::stream_base::server,
+ buffer(const_char_buffer), lazy);
+ (void)i6;
+
+ stream1.shutdown();
+ stream1.shutdown(ec);
+
+ stream1.async_shutdown(shutdown_handler);
+ int i7 = stream1.async_shutdown(lazy);
+ (void)i7;
+
+ stream1.write_some(buffer(mutable_char_buffer));
+ stream1.write_some(buffer(const_char_buffer));
+ stream1.write_some(buffer(mutable_char_buffer), ec);
+ stream1.write_some(buffer(const_char_buffer), ec);
+
+ stream1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
+ stream1.async_write_some(buffer(const_char_buffer), write_some_handler);
+ int i8 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i8;
+ int i9 = stream1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i9;
+
+ stream1.read_some(buffer(mutable_char_buffer));
+ stream1.read_some(buffer(mutable_char_buffer), ec);
+
+ stream1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+ int i10 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i10;
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ssl_stream_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "ssl/stream",
+ ASIO_TEST_CASE(ssl_stream_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/ssl/stream_base.cpp b/3rdparty/asio/src/tests/unit/ssl/stream_base.cpp
new file mode 100644
index 00000000000..4dbc9e3b232
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/ssl/stream_base.cpp
@@ -0,0 +1,25 @@
+//
+// stream_base.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/ssl/stream_base.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "ssl/stream_base",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/steady_timer.cpp b/3rdparty/asio/src/tests/unit/steady_timer.cpp
new file mode 100644
index 00000000000..18d4a8152fe
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/steady_timer.cpp
@@ -0,0 +1,30 @@
+//
+// steady_timer.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Prevent link dependency on the Boost.System library.
+#if !defined(BOOST_SYSTEM_NO_DEPRECATED)
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif // !defined(BOOST_SYSTEM_NO_DEPRECATED)
+
+// Test that header file is self-contained.
+#include "asio/steady_timer.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "steady_timer",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/strand.cpp b/3rdparty/asio/src/tests/unit/strand.cpp
new file mode 100644
index 00000000000..02a0f7d58fa
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/strand.cpp
@@ -0,0 +1,224 @@
+//
+// strand.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/strand.hpp"
+
+#include <sstream>
+#include "asio/io_context.hpp"
+#include "asio/dispatch.hpp"
+#include "asio/post.hpp"
+#include "asio/thread.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+# include "asio/deadline_timer.hpp"
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+# include "asio/steady_timer.hpp"
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+using namespace asio;
+
+#if defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = std;
+#endif
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+typedef deadline_timer timer;
+namespace chronons = boost::posix_time;
+#elif defined(ASIO_HAS_CHRONO)
+typedef steady_timer timer;
+namespace chronons = asio::chrono;
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+
+void increment(int* count)
+{
+ ++(*count);
+}
+
+void increment_without_lock(io_context::strand* s, int* count)
+{
+ ASIO_CHECK(!s->running_in_this_thread());
+
+ int original_count = *count;
+
+ dispatch(*s, bindns::bind(increment, count));
+
+ // No other functions are currently executing through the locking dispatcher,
+ // so the previous call to dispatch should have successfully nested.
+ ASIO_CHECK(*count == original_count + 1);
+}
+
+void increment_with_lock(io_context::strand* s, int* count)
+{
+ ASIO_CHECK(s->running_in_this_thread());
+
+ int original_count = *count;
+
+ dispatch(*s, bindns::bind(increment, count));
+
+ // The current function already holds the strand's lock, so the
+ // previous call to dispatch should have successfully nested.
+ ASIO_CHECK(*count == original_count + 1);
+}
+
+void sleep_increment(io_context* ioc, int* count)
+{
+ timer t(*ioc, chronons::seconds(2));
+ t.wait();
+
+ ++(*count);
+}
+
+void start_sleep_increments(io_context* ioc, io_context::strand* s, int* count)
+{
+ // Give all threads a chance to start.
+ timer t(*ioc, chronons::seconds(2));
+ t.wait();
+
+ // Start three increments.
+ post(*s, bindns::bind(sleep_increment, ioc, count));
+ post(*s, bindns::bind(sleep_increment, ioc, count));
+ post(*s, bindns::bind(sleep_increment, ioc, count));
+}
+
+void throw_exception()
+{
+ throw 1;
+}
+
+void io_context_run(io_context* ioc)
+{
+ ioc->run();
+}
+
+void strand_test()
+{
+ io_context ioc;
+ io_context::strand s(ioc);
+ int count = 0;
+
+ post(ioc, bindns::bind(increment_without_lock, &s, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(count == 1);
+
+ count = 0;
+ ioc.restart();
+ post(s, bindns::bind(increment_with_lock, &s, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all work has finished.
+ ASIO_CHECK(count == 1);
+
+ count = 0;
+ ioc.restart();
+ post(ioc, bindns::bind(start_sleep_increments, &ioc, &s, &count));
+ thread thread1(bindns::bind(io_context_run, &ioc));
+ thread thread2(bindns::bind(io_context_run, &ioc));
+
+ // Check all events run one after another even though there are two threads.
+ timer timer1(ioc, chronons::seconds(3));
+ timer1.wait();
+ ASIO_CHECK(count == 0);
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.expires_at(timer1.expires_at() + chronons::seconds(2));
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.expires_at(timer1.expiry() + chronons::seconds(2));
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.wait();
+ ASIO_CHECK(count == 1);
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.expires_at(timer1.expires_at() + chronons::seconds(2));
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.expires_at(timer1.expiry() + chronons::seconds(2));
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+ timer1.wait();
+ ASIO_CHECK(count == 2);
+
+ thread1.join();
+ thread2.join();
+
+ // The run() calls will not return until all work has finished.
+ ASIO_CHECK(count == 3);
+
+ count = 0;
+ int exception_count = 0;
+ ioc.restart();
+ post(s, throw_exception);
+ post(s, bindns::bind(increment, &count));
+ post(s, bindns::bind(increment, &count));
+ post(s, throw_exception);
+ post(s, bindns::bind(increment, &count));
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(count == 0);
+ ASIO_CHECK(exception_count == 0);
+
+ for (;;)
+ {
+ try
+ {
+ ioc.run();
+ break;
+ }
+ catch (int)
+ {
+ ++exception_count;
+ }
+ }
+
+ // The run() calls will not return until all work has finished.
+ ASIO_CHECK(count == 3);
+ ASIO_CHECK(exception_count == 2);
+
+ count = 0;
+ ioc.restart();
+
+ // Check for clean shutdown when handlers posted through an orphaned strand
+ // are abandoned.
+ {
+ io_context::strand s2(ioc);
+ post(s2, bindns::bind(increment, &count));
+ post(s2, bindns::bind(increment, &count));
+ post(s2, bindns::bind(increment, &count));
+ }
+
+ // No handlers can be called until run() is called.
+ ASIO_CHECK(count == 0);
+}
+
+ASIO_TEST_SUITE
+(
+ "strand",
+ ASIO_TEST_CASE(strand_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/stream_socket_service.cpp b/3rdparty/asio/src/tests/unit/stream_socket_service.cpp
new file mode 100644
index 00000000000..03bbbf2f475
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/stream_socket_service.cpp
@@ -0,0 +1,25 @@
+//
+// stream_socket_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/stream_socket_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "stream_socket_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/streambuf.cpp b/3rdparty/asio/src/tests/unit/streambuf.cpp
new file mode 100644
index 00000000000..5e10e726d1c
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/streambuf.cpp
@@ -0,0 +1,62 @@
+//
+// streambuf.cpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/streambuf.hpp"
+
+#include "asio/buffer.hpp"
+#include "unit_test.hpp"
+
+void streambuf_test()
+{
+ asio::streambuf sb;
+
+ sb.sputn("abcd", 4);
+
+ ASIO_CHECK(sb.size() == 4);
+
+ for (int i = 0; i < 100; ++i)
+ {
+ sb.consume(3);
+
+ ASIO_CHECK(sb.size() == 1);
+
+ char buf[1];
+ sb.sgetn(buf, 1);
+
+ ASIO_CHECK(sb.size() == 0);
+
+ sb.sputn("ab", 2);
+
+ ASIO_CHECK(sb.size() == 2);
+
+ asio::buffer_copy(sb.prepare(10), asio::buffer("cd", 2));
+ sb.commit(2);
+
+ ASIO_CHECK(sb.size() == 4);
+ }
+
+ ASIO_CHECK(sb.size() == 4);
+
+ sb.consume(4);
+
+ ASIO_CHECK(sb.size() == 0);
+}
+
+ASIO_TEST_SUITE
+(
+ "streambuf",
+ ASIO_TEST_CASE(streambuf_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/system_timer.cpp b/3rdparty/asio/src/tests/unit/system_timer.cpp
new file mode 100644
index 00000000000..3f77a2e74dc
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/system_timer.cpp
@@ -0,0 +1,400 @@
+//
+// system_timer.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Prevent link dependency on the Boost.System library.
+#if !defined(BOOST_SYSTEM_NO_DEPRECATED)
+#define BOOST_SYSTEM_NO_DEPRECATED
+#endif // !defined(BOOST_SYSTEM_NO_DEPRECATED)
+
+// Test that header file is self-contained.
+#include "asio/system_timer.hpp"
+
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_STD_CHRONO)
+
+#include "asio/executor_work_guard.hpp"
+#include "asio/io_context.hpp"
+#include "asio/thread.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+namespace bindns = std;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+void increment(int* count)
+{
+ ++(*count);
+}
+
+void decrement_to_zero(asio::system_timer* t, int* count)
+{
+ if (*count > 0)
+ {
+ --(*count);
+
+ int before_value = *count;
+
+ t->expires_at(t->expiry() + asio::chrono::seconds(1));
+ t->async_wait(bindns::bind(decrement_to_zero, t, count));
+
+ // Completion cannot nest, so count value should remain unchanged.
+ ASIO_CHECK(*count == before_value);
+ }
+}
+
+void increment_if_not_cancelled(int* count,
+ const asio::error_code& ec)
+{
+ if (!ec)
+ ++(*count);
+}
+
+void cancel_timer(asio::system_timer* t)
+{
+ std::size_t num_cancelled = t->cancel();
+ ASIO_CHECK(num_cancelled == 1);
+}
+
+void cancel_one_timer(asio::system_timer* t)
+{
+ std::size_t num_cancelled = t->cancel_one();
+ ASIO_CHECK(num_cancelled == 1);
+}
+
+asio::system_timer::time_point now()
+{
+ return asio::system_timer::clock_type::now();
+}
+
+void system_timer_test()
+{
+ using asio::chrono::seconds;
+ using asio::chrono::microseconds;
+#if !defined(ASIO_HAS_BOOST_BIND)
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // !defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ int count = 0;
+
+ asio::system_timer::time_point start = now();
+
+ asio::system_timer t1(ioc, seconds(1));
+ t1.wait();
+
+ // The timer must block until after its expiry time.
+ asio::system_timer::time_point end = now();
+ asio::system_timer::time_point expected_end = start + seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ asio::system_timer t2(ioc, seconds(1) + microseconds(500000));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end = start + seconds(1) + microseconds(500000);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ t2.expires_at(t2.expiry() + seconds(1));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end += seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ t2.expires_after(seconds(1) + microseconds(200000));
+ t2.wait();
+
+ // The timer must block until after its expiry time.
+ end = now();
+ expected_end = start + seconds(1) + microseconds(200000);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ start = now();
+
+ asio::system_timer t3(ioc, seconds(5));
+ t3.async_wait(bindns::bind(increment, &count));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.run();
+
+ // The run() call will not return until all operations have finished, and
+ // this should not be until after the timer's expiry time.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(1);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 3;
+ start = now();
+
+ asio::system_timer t4(ioc, seconds(1));
+ t4.async_wait(bindns::bind(decrement_to_zero, &t4, &count));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 3);
+
+ ioc.restart();
+ ioc.run();
+
+ // The run() call will not return until all operations have finished, and
+ // this should not be until after the timer's final expiry time.
+ ASIO_CHECK(count == 0);
+ end = now();
+ expected_end = start + seconds(3);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 0;
+ start = now();
+
+ asio::system_timer t5(ioc, seconds(10));
+ t5.async_wait(bindns::bind(increment_if_not_cancelled, &count, _1));
+ asio::system_timer t6(ioc, seconds(1));
+ t6.async_wait(bindns::bind(cancel_timer, &t5));
+
+ // No completions can be delivered until run() is called.
+ ASIO_CHECK(count == 0);
+
+ ioc.restart();
+ ioc.run();
+
+ // The timer should have been cancelled, so count should not have changed.
+ // The total run time should not have been much more than 1 second (and
+ // certainly far less than 10 seconds).
+ ASIO_CHECK(count == 0);
+ end = now();
+ expected_end = start + seconds(2);
+ ASIO_CHECK(end < expected_end);
+
+ // Wait on the timer again without cancelling it. This time the asynchronous
+ // wait should run to completion and increment the counter.
+ t5.async_wait(bindns::bind(increment_if_not_cancelled, &count, _1));
+
+ ioc.restart();
+ ioc.run();
+
+ // The timer should not have been cancelled, so count should have changed.
+ // The total time since the timer was created should be more than 10 seconds.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(10);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+
+ count = 0;
+ start = now();
+
+ // Start two waits on a timer, one of which will be cancelled. The one
+ // which is not cancelled should still run to completion and increment the
+ // counter.
+ asio::system_timer t7(ioc, seconds(3));
+ t7.async_wait(bindns::bind(increment_if_not_cancelled, &count, _1));
+ t7.async_wait(bindns::bind(increment_if_not_cancelled, &count, _1));
+ asio::system_timer t8(ioc, seconds(1));
+ t8.async_wait(bindns::bind(cancel_one_timer, &t7));
+
+ ioc.restart();
+ ioc.run();
+
+ // One of the waits should not have been cancelled, so count should have
+ // changed. The total time since the timer was created should be more than 3
+ // seconds.
+ ASIO_CHECK(count == 1);
+ end = now();
+ expected_end = start + seconds(3);
+ ASIO_CHECK(expected_end < end || expected_end == end);
+}
+
+struct timer_handler
+{
+ timer_handler() {}
+ void operator()(const asio::error_code&) {}
+#if defined(ASIO_HAS_MOVE)
+ timer_handler(timer_handler&&) {}
+private:
+ timer_handler(const timer_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
+
+void system_timer_cancel_test()
+{
+ static asio::io_context io_context;
+ struct timer
+ {
+ asio::system_timer t;
+ timer() : t(io_context)
+ {
+ t.expires_at((asio::system_timer::time_point::max)());
+ }
+ } timers[50];
+
+ timers[2].t.async_wait(timer_handler());
+ timers[41].t.async_wait(timer_handler());
+ for (int i = 10; i < 20; ++i)
+ timers[i].t.async_wait(timer_handler());
+
+ ASIO_CHECK(timers[2].t.cancel() == 1);
+ ASIO_CHECK(timers[41].t.cancel() == 1);
+ for (int i = 10; i < 20; ++i)
+ ASIO_CHECK(timers[i].t.cancel() == 1);
+}
+
+struct custom_allocation_timer_handler
+{
+ custom_allocation_timer_handler(int* count) : count_(count) {}
+ void operator()(const asio::error_code&) {}
+ int* count_;
+};
+
+void* asio_handler_allocate(std::size_t size,
+ custom_allocation_timer_handler* handler)
+{
+ ++(*handler->count_);
+ return ::operator new(size);
+}
+
+void asio_handler_deallocate(void* pointer, std::size_t,
+ custom_allocation_timer_handler* handler)
+{
+ --(*handler->count_);
+ ::operator delete(pointer);
+}
+
+void system_timer_custom_allocation_test()
+{
+ static asio::io_context io_context;
+ struct timer
+ {
+ asio::system_timer t;
+ timer() : t(io_context) {}
+ } timers[100];
+
+ int allocation_count = 0;
+
+ for (int i = 0; i < 50; ++i)
+ {
+ timers[i].t.expires_at((asio::system_timer::time_point::max)());
+ timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
+ }
+
+ for (int i = 50; i < 100; ++i)
+ {
+ timers[i].t.expires_at((asio::system_timer::time_point::min)());
+ timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
+ }
+
+ for (int i = 0; i < 50; ++i)
+ timers[i].t.cancel();
+
+ io_context.run();
+
+ ASIO_CHECK(allocation_count == 0);
+}
+
+void io_context_run(asio::io_context* ioc)
+{
+ ioc->run();
+}
+
+void system_timer_thread_test()
+{
+ asio::io_context ioc;
+ asio::executor_work_guard<asio::io_context::executor_type> work
+ = asio::make_work_guard(ioc);
+ asio::system_timer t1(ioc);
+ asio::system_timer t2(ioc);
+ int count = 0;
+
+ asio::thread th(bindns::bind(io_context_run, &ioc));
+
+ t2.expires_after(asio::chrono::seconds(2));
+ t2.wait();
+
+ t1.expires_after(asio::chrono::seconds(2));
+ t1.async_wait(bindns::bind(increment, &count));
+
+ t2.expires_after(asio::chrono::seconds(4));
+ t2.wait();
+
+ ioc.stop();
+ th.join();
+
+ ASIO_CHECK(count == 1);
+}
+
+#if defined(ASIO_HAS_MOVE)
+asio::system_timer make_timer(asio::io_context& ioc, int* count)
+{
+ asio::system_timer t(ioc);
+ t.expires_after(asio::chrono::seconds(1));
+ t.async_wait(bindns::bind(increment, count));
+ return t;
+}
+#endif
+
+void system_timer_move_test()
+{
+#if defined(ASIO_HAS_MOVE)
+ asio::io_context io_context1;
+ asio::io_context io_context2;
+ int count = 0;
+
+ asio::system_timer t1 = make_timer(io_context1, &count);
+ asio::system_timer t2 = make_timer(io_context2, &count);
+ asio::system_timer t3 = std::move(t1);
+
+ t2 = std::move(t1);
+
+ io_context2.run();
+
+ ASIO_CHECK(count == 1);
+
+ io_context1.run();
+
+ ASIO_CHECK(count == 2);
+#endif // defined(ASIO_HAS_MOVE)
+}
+
+ASIO_TEST_SUITE
+(
+ "system_timer",
+ ASIO_TEST_CASE(system_timer_test)
+ ASIO_TEST_CASE(system_timer_cancel_test)
+ ASIO_TEST_CASE(system_timer_custom_allocation_test)
+ ASIO_TEST_CASE(system_timer_thread_test)
+ ASIO_TEST_CASE(system_timer_move_test)
+)
+#else // defined(ASIO_HAS_STD_CHRONO)
+ASIO_TEST_SUITE
+(
+ "system_timer",
+ ASIO_TEST_CASE(null_test)
+)
+#endif // defined(ASIO_HAS_STD_CHRONO)
diff --git a/3rdparty/asio/src/tests/unit/thread.cpp b/3rdparty/asio/src/tests/unit/thread.cpp
new file mode 100644
index 00000000000..4096c9a7959
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/thread.cpp
@@ -0,0 +1,25 @@
+//
+// thread.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/thread.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "thread",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/time_traits.cpp b/3rdparty/asio/src/tests/unit/time_traits.cpp
new file mode 100644
index 00000000000..64a35a13a2b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/time_traits.cpp
@@ -0,0 +1,25 @@
+//
+// time_traits.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/time_traits.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "time_traits",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/unit_test.hpp b/3rdparty/asio/src/tests/unit/unit_test.hpp
new file mode 100644
index 00000000000..b74c3d4ec41
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/unit_test.hpp
@@ -0,0 +1,175 @@
+//
+// unit_test.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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 UNIT_TEST_HPP
+#define UNIT_TEST_HPP
+
+#include "asio/detail/config.hpp"
+#include <iostream>
+#include "asio/detail/atomic_count.hpp"
+
+#if defined(__sun)
+# include <stdlib.h> // Needed for lrand48.
+#endif // defined(__sun)
+
+#if defined(__BORLANDC__)
+
+// Prevent use of intrinsic for strcmp.
+# include <cstring>
+# undef strcmp
+
+// Suppress error about condition always being true.
+# pragma option -w-ccc
+
+#endif // defined(__BORLANDC__)
+
+#if defined(ASIO_MSVC)
+# pragma warning (disable:4127)
+# pragma warning (push)
+# pragma warning (disable:4244)
+# pragma warning (disable:4702)
+#endif // defined(ASIO_MSVC)
+
+#if !defined(ASIO_TEST_IOSTREAM)
+# define ASIO_TEST_IOSTREAM std::cerr
+#endif // !defined(ASIO_TEST_IOSTREAM)
+
+namespace asio {
+namespace detail {
+
+inline const char*& test_name()
+{
+ static const char* name = 0;
+ return name;
+}
+
+inline atomic_count& test_errors()
+{
+ static atomic_count errors(0);
+ return errors;
+}
+
+inline void begin_test_suite(const char* name)
+{
+ asio::detail::test_name();
+ asio::detail::test_errors();
+ ASIO_TEST_IOSTREAM << name << " test suite begins" << std::endl;
+}
+
+inline int end_test_suite(const char* name)
+{
+ ASIO_TEST_IOSTREAM << name << " test suite ends" << std::endl;
+ ASIO_TEST_IOSTREAM << "\n*** ";
+ long errors = asio::detail::test_errors();
+ if (errors == 0)
+ ASIO_TEST_IOSTREAM << "No errors detected.";
+ else if (errors == 1)
+ ASIO_TEST_IOSTREAM << "1 error detected.";
+ else
+ ASIO_TEST_IOSTREAM << errors << " errors detected." << std::endl;
+ ASIO_TEST_IOSTREAM << std::endl;
+ return errors == 0 ? 0 : 1;
+}
+
+template <void (*Test)()>
+inline void run_test(const char* name)
+{
+ test_name() = name;
+ long errors_before = asio::detail::test_errors();
+ Test();
+ if (test_errors() == errors_before)
+ ASIO_TEST_IOSTREAM << name << " passed" << std::endl;
+ else
+ ASIO_TEST_IOSTREAM << name << " failed" << std::endl;
+}
+
+template <void (*)()>
+inline void compile_test(const char* name)
+{
+ ASIO_TEST_IOSTREAM << name << " passed" << std::endl;
+}
+
+#if defined(ASIO_NO_EXCEPTIONS)
+
+template <typename T>
+void throw_exception(const T& t)
+{
+ ASIO_TEST_IOSTREAM << "Exception: " << t.what() << std::endl;
+ std::abort();
+}
+
+#endif // defined(ASIO_NO_EXCEPTIONS)
+
+} // namespace detail
+} // namespace asio
+
+#define ASIO_CHECK(expr) \
+ do { if (!(expr)) { \
+ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
+ << asio::detail::test_name() << ": " \
+ << "check '" << #expr << "' failed" << std::endl; \
+ ++asio::detail::test_errors(); \
+ } } while (0)
+
+#define ASIO_CHECK_MESSAGE(expr, msg) \
+ do { if (!(expr)) { \
+ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
+ << asio::detail::test_name() << ": " \
+ << msg << std::endl; \
+ ++asio::detail::test_errors(); \
+ } } while (0)
+
+#define ASIO_WARN_MESSAGE(expr, msg) \
+ do { if (!(expr)) { \
+ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
+ << asio::detail::test_name() << ": " \
+ << msg << std::endl; \
+ } } while (0)
+
+#define ASIO_ERROR(msg) \
+ do { \
+ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
+ << asio::detail::test_name() << ": " \
+ << msg << std::endl; \
+ ++asio::detail::test_errors(); \
+ } while (0)
+
+#define ASIO_TEST_SUITE(name, tests) \
+ int main() \
+ { \
+ asio::detail::begin_test_suite(name); \
+ tests \
+ return asio::detail::end_test_suite(name); \
+ }
+
+#define ASIO_TEST_CASE(test) \
+ asio::detail::run_test<&test>(#test);
+
+#define ASIO_COMPILE_TEST_CASE(test) \
+ asio::detail::compile_test<&test>(#test);
+
+inline void null_test()
+{
+}
+
+#if defined(__GNUC__) && defined(_AIX)
+
+// AIX needs this symbol defined in asio, even if it doesn't do anything.
+int test_main(int, char**)
+{
+}
+
+#endif // defined(__GNUC__) && defined(_AIX)
+
+#if defined(ASIO_MSVC)
+# pragma warning (pop)
+#endif // defined(ASIO_MSVC)
+
+#endif // UNIT_TEST_HPP
diff --git a/3rdparty/asio/src/tests/unit/use_future.cpp b/3rdparty/asio/src/tests/unit/use_future.cpp
new file mode 100644
index 00000000000..bc6e3b859b6
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/use_future.cpp
@@ -0,0 +1,1346 @@
+//
+// use_future.cpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/use_future.hpp"
+
+#include <string>
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_STD_FUTURE)
+
+#include "archetypes/async_ops.hpp"
+#include "archetypes/deprecated_async_ops.hpp"
+
+void use_future_0_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<void> f;
+
+ f = async_op_0(use_future);
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_0(true, use_future);
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_0(false, use_future);
+ try
+ {
+ f.get();
+ ASIO_CHECK(false);
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(true, use_future);
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(false, use_future);
+ try
+ {
+ f.get();
+ ASIO_CHECK(false);
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+void use_future_1_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+
+ f = async_op_1(use_future);
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_1(true, use_future);
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_1(false, use_future);
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(false);
+ (void)i;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_1(true, use_future);
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_1(false, use_future);
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(false);
+ (void)i;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+void use_future_2_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<std::tuple<int, double>> f;
+
+ f = async_op_2(use_future);
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_2(true, use_future);
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_2(false, use_future);
+ try
+ {
+ std::tuple<int, double> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_2(true, use_future);
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_2(false, use_future);
+ try
+ {
+ std::tuple<int, double> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+void use_future_3_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<std::tuple<int, double, char>> f;
+
+ f = async_op_3(use_future);
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_3(true, use_future);
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_3(false, use_future);
+ try
+ {
+ std::tuple<int, double, char> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_3(true, use_future);
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_3(false, use_future);
+ try
+ {
+ std::tuple<int, double, char> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+int package_0()
+{
+ return 42;
+}
+
+int package_ec_0(asio::error_code ec)
+{
+ return ec ? 0 : 42;
+}
+
+int package_ex_0(std::exception_ptr ex)
+{
+ return ex ? 0 : 42;
+}
+
+void use_future_package_0_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+
+ f = async_op_0(use_future(package_0));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_0(true, use_future(&package_ec_0));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_0(false, use_future(package_ec_0));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(true, use_future(package_ex_0));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(false, use_future(package_ex_0));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+int package_1(int i)
+{
+ return i;
+}
+
+int package_ec_1(asio::error_code ec, int i)
+{
+ return ec ? 0 : i;
+}
+
+int package_ex_1(std::exception_ptr ex, int i)
+{
+ return ex ? 0 : i;
+}
+
+void use_future_package_1_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+
+ f = async_op_1(use_future(package_1));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_1(true, use_future(package_ec_1));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_1(false, use_future(package_ec_1));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_1(true, use_future(package_ex_1));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_1(false, use_future(package_ex_1));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+int package_2(int i, double)
+{
+ return i;
+}
+
+int package_ec_2(asio::error_code ec, int i, double)
+{
+ return ec ? 0 : i;
+}
+
+int package_ex_2(std::exception_ptr ex, int i, double)
+{
+ return ex ? 0 : i;
+}
+
+void use_future_package_2_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+
+ f = async_op_2(use_future(package_2));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_2(true, use_future(package_ec_2));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_2(false, use_future(package_ec_2));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_2(true, use_future(package_ex_2));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_2(false, use_future(package_ex_2));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+int package_3(int i, double, char)
+{
+ return i;
+}
+
+int package_ec_3(asio::error_code ec, int i, double, char)
+{
+ return ec ? 0 : i;
+}
+
+int package_ex_3(std::exception_ptr ex, int i, double, char)
+{
+ return ex ? 0 : i;
+}
+
+void use_future_package_3_test()
+{
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+
+ f = async_op_3(use_future(package_3));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_3(true, use_future(package_ec_3));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ec_3(false, use_future(package_ec_3));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_3(true, use_future(package_ex_3));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_3(false, use_future(package_ex_3));
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+}
+
+void deprecated_use_future_0_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<void> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_0(ctx, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_0(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_0(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ f.get();
+ ASIO_CHECK(false);
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ f.get();
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = async_op_ex_0(false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ f.get();
+ ASIO_CHECK(false);
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_1_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_1(ctx, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_1(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_1(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(false);
+ (void)i;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_1(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_1(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(false);
+ (void)i;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_2_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<std::tuple<int, double>> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_2(ctx, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_2(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_2(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ std::tuple<int, double> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_2(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ std::tie(i, d) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_2(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ std::tuple<int, double> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_3_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<std::tuple<int, double, char>> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_3(ctx, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_3(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_3(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ std::tuple<int, double, char> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (asio::system_error& e)
+ {
+ ASIO_CHECK(e.code() == asio::error::operation_aborted);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_3(ctx, true, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i;
+ double d;
+ char c;
+ std::tie(i, d, c) = f.get();
+ ASIO_CHECK(i == 42);
+ ASIO_CHECK(d == 2.0);
+ ASIO_CHECK(c == 'a');
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_3(ctx, false, use_future);
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ std::tuple<int, double, char> t = f.get();
+ ASIO_CHECK(false);
+ (void)t;
+ }
+ catch (std::exception& e)
+ {
+ ASIO_CHECK(e.what() == std::string("blah"));
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_package_0_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_0(ctx, use_future(package_0));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_0(ctx, true, use_future(&package_ec_0));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_0(ctx, false, use_future(package_ec_0));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_0(ctx, true, use_future(package_ex_0));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_0(ctx, false, use_future(package_ex_0));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_package_1_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_1(ctx, use_future(package_1));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_1(ctx, true, use_future(package_ec_1));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_1(ctx, false, use_future(package_ec_1));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_1(ctx, true, use_future(package_ex_1));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_1(ctx, false, use_future(package_ex_1));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_package_2_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_2(ctx, use_future(package_2));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_2(ctx, true, use_future(package_ec_2));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_2(ctx, false, use_future(package_ec_2));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_2(ctx, true, use_future(package_ex_2));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_2(ctx, false, use_future(package_ex_2));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+void deprecated_use_future_package_3_test()
+{
+#if !defined(ASIO_NO_DEPRECATED)
+ using asio::use_future;
+ using namespace archetypes;
+
+ std::future<int> f;
+ asio::io_context ctx;
+
+ f = deprecated_async_op_3(ctx, use_future(package_3));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_3(ctx, true, use_future(package_ec_3));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ec_3(ctx, false, use_future(package_ec_3));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_3(ctx, true, use_future(package_ex_3));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 42);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+
+ f = deprecated_async_op_ex_3(ctx, false, use_future(package_ex_3));
+ ctx.restart();
+ ctx.run();
+ try
+ {
+ int i = f.get();
+ ASIO_CHECK(i == 0);
+ }
+ catch (...)
+ {
+ ASIO_CHECK(false);
+ }
+#endif // !defined(ASIO_NO_DEPRECATED)
+}
+
+ASIO_TEST_SUITE
+(
+ "use_future",
+ ASIO_TEST_CASE(use_future_0_test)
+ ASIO_TEST_CASE(use_future_1_test)
+ ASIO_TEST_CASE(use_future_2_test)
+ ASIO_TEST_CASE(use_future_3_test)
+ ASIO_TEST_CASE(use_future_package_0_test)
+ ASIO_TEST_CASE(use_future_package_1_test)
+ ASIO_TEST_CASE(use_future_package_2_test)
+ ASIO_TEST_CASE(use_future_package_3_test)
+ ASIO_TEST_CASE(deprecated_use_future_0_test)
+ ASIO_TEST_CASE(deprecated_use_future_1_test)
+ ASIO_TEST_CASE(deprecated_use_future_2_test)
+ ASIO_TEST_CASE(deprecated_use_future_3_test)
+ ASIO_TEST_CASE(deprecated_use_future_package_0_test)
+ ASIO_TEST_CASE(deprecated_use_future_package_1_test)
+ ASIO_TEST_CASE(deprecated_use_future_package_2_test)
+ ASIO_TEST_CASE(deprecated_use_future_package_3_test)
+)
+
+#else // defined(ASIO_HAS_STD_FUTURE)
+
+ASIO_TEST_SUITE
+(
+ "use_future",
+ ASIO_TEST_CASE(null_test)
+)
+
+#endif // defined(ASIO_HAS_STD_FUTURE)
diff --git a/3rdparty/asio/src/tests/unit/uses_executor.cpp b/3rdparty/asio/src/tests/unit/uses_executor.cpp
new file mode 100644
index 00000000000..cb1e2918b13
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/uses_executor.cpp
@@ -0,0 +1,25 @@
+//
+// uses_executor.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/uses_executor.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "uses_executor",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/wait_traits.cpp b/3rdparty/asio/src/tests/unit/wait_traits.cpp
new file mode 100644
index 00000000000..eed0161273c
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/wait_traits.cpp
@@ -0,0 +1,25 @@
+//
+// wait_traits.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/wait_traits.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "wait_traits",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/waitable_timer_service.cpp b/3rdparty/asio/src/tests/unit/waitable_timer_service.cpp
new file mode 100644
index 00000000000..3aa530aab75
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/waitable_timer_service.cpp
@@ -0,0 +1,25 @@
+//
+// waitable_timer_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/waitable_timer_service.hpp"
+
+#include "unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "waitable_timer_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/.gitignore b/3rdparty/asio/src/tests/unit/windows/.gitignore
new file mode 100644
index 00000000000..d225c81cd76
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/.gitignore
@@ -0,0 +1,21 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+basic_handle
+basic_object_handle
+basic_random_access_handle
+basic_stream_handle
+object_handle
+object_handle_service
+overlapped_handle
+overlapped_ptr
+random_access_handle
+random_access_handle_service
+stream_handle
+stream_handle_service
diff --git a/3rdparty/asio/src/tests/unit/windows/basic_handle.cpp b/3rdparty/asio/src/tests/unit/windows/basic_handle.cpp
new file mode 100644
index 00000000000..572699e2cfa
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/basic_handle.cpp
@@ -0,0 +1,26 @@
+//
+// basic_handle.cpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/basic_handle.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/basic_handle",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/basic_object_handle.cpp b/3rdparty/asio/src/tests/unit/windows/basic_object_handle.cpp
new file mode 100644
index 00000000000..4c27e14e488
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/basic_object_handle.cpp
@@ -0,0 +1,26 @@
+//
+// basic_object_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/basic_object_handle.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/basic_object_handle",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/basic_random_access_handle.cpp b/3rdparty/asio/src/tests/unit/windows/basic_random_access_handle.cpp
new file mode 100644
index 00000000000..720cf76b749
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/basic_random_access_handle.cpp
@@ -0,0 +1,26 @@
+//
+// basic_random_access_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/basic_random_access_handle.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/basic_random_access_handle",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/basic_stream_handle.cpp b/3rdparty/asio/src/tests/unit/windows/basic_stream_handle.cpp
new file mode 100644
index 00000000000..2151dafb709
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/basic_stream_handle.cpp
@@ -0,0 +1,26 @@
+//
+// basic_stream_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/basic_stream_handle.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/basic_stream_handle",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/object_handle.cpp b/3rdparty/asio/src/tests/unit/windows/object_handle.cpp
new file mode 100644
index 00000000000..32a836ef208
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/object_handle.cpp
@@ -0,0 +1,126 @@
+//
+// object_handle.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/object_handle.hpp"
+
+#include "asio/io_context.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// windows_object_handle_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// windows::object_handle compile and link correctly. Runtime failures are
+// ignored.
+
+namespace windows_object_handle_compile {
+
+void wait_handler(const asio::error_code&)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)
+ using namespace asio;
+ namespace win = asio::windows;
+
+ try
+ {
+ io_context ioc;
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_object_handle constructors.
+
+ win::object_handle handle1(ioc);
+ HANDLE native_handle1 = INVALID_HANDLE_VALUE;
+ win::object_handle handle2(ioc, native_handle1);
+
+#if defined(ASIO_HAS_MOVE)
+ win::object_handle handle3(std::move(handle2));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_object_handle operators.
+
+#if defined(ASIO_HAS_MOVE)
+ handle1 = win::object_handle(ioc);
+ handle1 = std::move(handle2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = handle1.get_io_context();
+ (void)ioc_ref;
+#endif !defined(ASIO_NO_DEPRECATED)
+
+ io_context::executor_type ex = handle1.get_executor();
+ (void)ex;
+
+ // basic_handle functions.
+
+ win::object_handle::lowest_layer_type& lowest_layer
+ = handle1.lowest_layer();
+ (void)lowest_layer;
+
+ const win::object_handle& handle4 = handle1;
+ const win::object_handle::lowest_layer_type& lowest_layer2
+ = handle4.lowest_layer();
+ (void)lowest_layer2;
+
+ HANDLE native_handle2 = INVALID_HANDLE_VALUE;
+ handle1.assign(native_handle2);
+
+ bool is_open = handle1.is_open();
+ (void)is_open;
+
+ handle1.close();
+ handle1.close(ec);
+
+ win::object_handle::native_handle_type native_handle3
+ = handle1.native_handle();
+ (void)native_handle3;
+
+ handle1.cancel();
+ handle1.cancel(ec);
+
+ // basic_object_handle functions.
+
+ handle1.wait();
+ handle1.wait(ec);
+
+ handle1.async_wait(&wait_handler);
+ int i1 = handle1.async_wait(lazy);
+ (void)i1;
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)
+}
+
+} // namespace windows_object_handle_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "windows/object_handle",
+ ASIO_TEST_CASE(windows_object_handle_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/object_handle_service.cpp b/3rdparty/asio/src/tests/unit/windows/object_handle_service.cpp
new file mode 100644
index 00000000000..56ff1c3bde9
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/object_handle_service.cpp
@@ -0,0 +1,26 @@
+//
+// object_handle_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/object_handle_service.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/object_handle_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/overlapped_handle.cpp b/3rdparty/asio/src/tests/unit/windows/overlapped_handle.cpp
new file mode 100644
index 00000000000..fbc8fb4e88b
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/overlapped_handle.cpp
@@ -0,0 +1,26 @@
+//
+// overlapped_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/overlapped_handle.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/overlapped_handle",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/overlapped_ptr.cpp b/3rdparty/asio/src/tests/unit/windows/overlapped_ptr.cpp
new file mode 100644
index 00000000000..261ece6f531
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/overlapped_ptr.cpp
@@ -0,0 +1,95 @@
+//
+// overlapped_ptr.cpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/overlapped_ptr.hpp"
+
+#include "asio/io_context.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// windows_overlapped_ptr_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// windows::overlapped_ptr compile and link correctly. Runtime failures are
+// ignored.
+
+namespace windows_overlapped_ptr_compile {
+
+void overlapped_handler_1(const asio::error_code&, std::size_t)
+{
+}
+
+struct overlapped_handler_2
+{
+ void operator()(const asio::error_code&, std::size_t)
+ {
+ }
+};
+
+void test()
+{
+#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+ using namespace asio;
+ namespace win = asio::windows;
+
+ try
+ {
+ io_context ioc;
+
+ // basic_overlapped_ptr constructors.
+
+ win::overlapped_ptr ptr1;
+
+ win::overlapped_ptr ptr2(ioc, &overlapped_handler_1);
+ win::overlapped_ptr ptr3(ioc, overlapped_handler_2());
+
+ // overlapped_ptr functions.
+
+ ptr1.reset();
+
+ ptr2.reset(ioc, &overlapped_handler_1);
+ ptr3.reset(ioc, overlapped_handler_2());
+
+ OVERLAPPED* ov1 = ptr1.get();
+ (void)ov1;
+
+ const win::overlapped_ptr& ptr4(ptr1);
+ const OVERLAPPED* ov2 = ptr4.get();
+ (void)ov2;
+
+ OVERLAPPED* ov3 = ptr1.release();
+ (void)ov3;
+
+ asio::error_code ec;
+ std::size_t bytes_transferred = 0;
+ ptr1.complete(ec, bytes_transferred);
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+}
+
+} // namespace windows_overlapped_ptr_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "windows/overlapped_ptr",
+ ASIO_TEST_CASE(windows_overlapped_ptr_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/random_access_handle.cpp b/3rdparty/asio/src/tests/unit/windows/random_access_handle.cpp
new file mode 100644
index 00000000000..fbd88209972
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/random_access_handle.cpp
@@ -0,0 +1,151 @@
+//
+// random_access_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/random_access_handle.hpp"
+
+#include "asio/io_context.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// windows_random_access_handle_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// windows::random_access_handle compile and link correctly. Runtime failures
+// are ignored.
+
+namespace windows_random_access_handle_compile {
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+ using namespace asio;
+ namespace win = asio::windows;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ asio::uint64_t offset = 0;
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_random_access_handle constructors.
+
+ win::random_access_handle handle1(ioc);
+ HANDLE native_handle1 = INVALID_HANDLE_VALUE;
+ win::random_access_handle handle2(ioc, native_handle1);
+
+#if defined(ASIO_HAS_MOVE)
+ win::random_access_handle handle3(std::move(handle2));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_random_access_handle operators.
+
+#if defined(ASIO_HAS_MOVE)
+ handle1 = win::random_access_handle(ioc);
+ handle1 = std::move(handle2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = handle1.get_io_context();
+ (void)ioc_ref;
+#endif !defined(ASIO_NO_DEPRECATED)
+
+ io_context::executor_type ex = handle1.get_executor();
+ (void)ex;
+
+ // basic_handle functions.
+
+ win::random_access_handle::lowest_layer_type& lowest_layer
+ = handle1.lowest_layer();
+ (void)lowest_layer;
+
+ const win::random_access_handle& handle4 = handle1;
+ const win::random_access_handle::lowest_layer_type& lowest_layer2
+ = handle4.lowest_layer();
+ (void)lowest_layer2;
+
+ HANDLE native_handle2 = INVALID_HANDLE_VALUE;
+ handle1.assign(native_handle2);
+
+ bool is_open = handle1.is_open();
+ (void)is_open;
+
+ handle1.close();
+ handle1.close(ec);
+
+ win::random_access_handle::native_handle_type native_handle3
+ = handle1.native_handle();
+ (void)native_handle3;
+
+ handle1.cancel();
+ handle1.cancel(ec);
+
+ // basic_random_access_handle functions.
+
+ handle1.write_some_at(offset, buffer(mutable_char_buffer));
+ handle1.write_some_at(offset, buffer(const_char_buffer));
+ handle1.write_some_at(offset, buffer(mutable_char_buffer), ec);
+ handle1.write_some_at(offset, buffer(const_char_buffer), ec);
+
+ handle1.async_write_some_at(offset,
+ buffer(mutable_char_buffer), &write_some_handler);
+ handle1.async_write_some_at(offset,
+ buffer(const_char_buffer), &write_some_handler);
+ int i1 = handle1.async_write_some_at(offset,
+ buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = handle1.async_write_some_at(offset,
+ buffer(const_char_buffer), lazy);
+ (void)i2;
+
+ handle1.read_some_at(offset, buffer(mutable_char_buffer));
+ handle1.read_some_at(offset, buffer(mutable_char_buffer), ec);
+
+ handle1.async_read_some_at(offset,
+ buffer(mutable_char_buffer), &read_some_handler);
+ int i3 = handle1.async_read_some_at(offset,
+ buffer(mutable_char_buffer), lazy);
+ (void)i3;
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+}
+
+} // namespace windows_random_access_handle_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "windows/random_access_handle",
+ ASIO_TEST_CASE(windows_random_access_handle_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/random_access_handle_service.cpp b/3rdparty/asio/src/tests/unit/windows/random_access_handle_service.cpp
new file mode 100644
index 00000000000..0895864d5b8
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/random_access_handle_service.cpp
@@ -0,0 +1,26 @@
+//
+// random_access_handle_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/random_access_handle_service.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/random_access_handle_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/stream_handle.cpp b/3rdparty/asio/src/tests/unit/windows/stream_handle.cpp
new file mode 100644
index 00000000000..499ed354b04
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/stream_handle.cpp
@@ -0,0 +1,144 @@
+//
+// stream_handle.cpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/stream_handle.hpp"
+
+#include "asio/io_context.hpp"
+#include "../archetypes/async_result.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// windows_stream_handle_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// windows::stream_handle compile and link correctly. Runtime failures are
+// ignored.
+
+namespace windows_stream_handle_compile {
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)
+ using namespace asio;
+ namespace win = asio::windows;
+
+ try
+ {
+ io_context ioc;
+ char mutable_char_buffer[128] = "";
+ const char const_char_buffer[128] = "";
+ archetypes::lazy_handler lazy;
+ asio::error_code ec;
+
+ // basic_stream_handle constructors.
+
+ win::stream_handle handle1(ioc);
+ HANDLE native_handle1 = INVALID_HANDLE_VALUE;
+ win::stream_handle handle2(ioc, native_handle1);
+
+#if defined(ASIO_HAS_MOVE)
+ win::stream_handle handle3(std::move(handle2));
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_stream_handle operators.
+
+#if defined(ASIO_HAS_MOVE)
+ handle1 = win::stream_handle(ioc);
+ handle1 = std::move(handle2);
+#endif // defined(ASIO_HAS_MOVE)
+
+ // basic_io_object functions.
+
+#if !defined(ASIO_NO_DEPRECATED)
+ io_context& ioc_ref = handle1.get_io_context();
+ (void)ioc_ref;
+#endif !defined(ASIO_NO_DEPRECATED)
+
+ io_context::executor_type ex = handle1.get_executor();
+ (void)ex;
+
+ // basic_handle functions.
+
+ win::stream_handle::lowest_layer_type& lowest_layer
+ = handle1.lowest_layer();
+ (void)lowest_layer;
+
+ const win::stream_handle& handle4 = handle1;
+ const win::stream_handle::lowest_layer_type& lowest_layer2
+ = handle4.lowest_layer();
+ (void)lowest_layer2;
+
+ HANDLE native_handle2 = INVALID_HANDLE_VALUE;
+ handle1.assign(native_handle2);
+
+ bool is_open = handle1.is_open();
+ (void)is_open;
+
+ handle1.close();
+ handle1.close(ec);
+
+ win::stream_handle::native_handle_type native_handle3
+ = handle1.native_handle();
+ (void)native_handle3;
+
+ handle1.cancel();
+ handle1.cancel(ec);
+
+ // basic_stream_handle functions.
+
+ handle1.write_some(buffer(mutable_char_buffer));
+ handle1.write_some(buffer(const_char_buffer));
+ handle1.write_some(buffer(mutable_char_buffer), ec);
+ handle1.write_some(buffer(const_char_buffer), ec);
+
+ handle1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
+ handle1.async_write_some(buffer(const_char_buffer), &write_some_handler);
+ int i1 = handle1.async_write_some(buffer(mutable_char_buffer), lazy);
+ (void)i1;
+ int i2 = handle1.async_write_some(buffer(const_char_buffer), lazy);
+ (void)i2;
+
+ handle1.read_some(buffer(mutable_char_buffer));
+ handle1.read_some(buffer(mutable_char_buffer), ec);
+
+ handle1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
+ int i3 = handle1.async_read_some(buffer(mutable_char_buffer), lazy);
+ (void)i3;
+ }
+ catch (std::exception&)
+ {
+ }
+#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)
+}
+
+} // namespace windows_stream_handle_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+ "windows/stream_handle",
+ ASIO_TEST_CASE(windows_stream_handle_compile::test)
+)
diff --git a/3rdparty/asio/src/tests/unit/windows/stream_handle_service.cpp b/3rdparty/asio/src/tests/unit/windows/stream_handle_service.cpp
new file mode 100644
index 00000000000..4281ee06b4f
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/windows/stream_handle_service.cpp
@@ -0,0 +1,26 @@
+//
+// stream_handle_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/windows/stream_handle_service.hpp"
+
+#include "asio.hpp"
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+ "windows/stream_handle_service",
+ ASIO_TEST_CASE(null_test)
+)
diff --git a/3rdparty/asio/src/tests/unit/write.cpp b/3rdparty/asio/src/tests/unit/write.cpp
new file mode 100644
index 00000000000..a60ee11ae45
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/write.cpp
@@ -0,0 +1,3922 @@
+//
+// write.cpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/write.hpp"
+
+#include <cstring>
+#include <vector>
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "asio/post.hpp"
+#include "asio/streambuf.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+#include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_stream
+{
+public:
+ typedef asio::io_context::executor_type executor_type;
+
+ test_stream(asio::io_context& io_context)
+ : io_context_(io_context),
+ length_(max_length),
+ position_(0),
+ next_write_length_(max_length)
+ {
+ memset(data_, 0, max_length);
+ }
+
+ executor_type get_executor() ASIO_NOEXCEPT
+ {
+ return io_context_.get_executor();
+ }
+
+ void reset(size_t length = max_length)
+ {
+ ASIO_CHECK(length <= max_length);
+
+ memset(data_, 0, max_length);
+ length_ = length;
+ position_ = 0;
+ next_write_length_ = length;
+ }
+
+ void next_write_length(size_t length)
+ {
+ next_write_length_ = length;
+ }
+
+ template <typename Iterator>
+ bool check_buffers(Iterator begin, Iterator end, size_t length)
+ {
+ if (length != position_)
+ return false;
+
+ Iterator iter = begin;
+ size_t checked_length = 0;
+ for (; iter != end && checked_length < length; ++iter)
+ {
+ size_t buffer_length = asio::buffer_size(*iter);
+ if (buffer_length > length - checked_length)
+ buffer_length = length - checked_length;
+ if (memcmp(data_ + checked_length, iter->data(), buffer_length) != 0)
+ return false;
+ checked_length += buffer_length;
+ }
+
+ return true;
+ }
+
+ template <typename Const_Buffers>
+ bool check_buffers(const Const_Buffers& buffers, size_t length)
+ {
+ return check_buffers(asio::buffer_sequence_begin(buffers),
+ asio::buffer_sequence_end(buffers), length);
+ }
+
+ template <typename Const_Buffers>
+ size_t write_some(const Const_Buffers& buffers)
+ {
+ size_t n = asio::buffer_copy(
+ asio::buffer(data_, length_) + position_,
+ buffers, next_write_length_);
+ position_ += n;
+ return n;
+ }
+
+ template <typename Const_Buffers>
+ size_t write_some(const Const_Buffers& buffers, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return write_some(buffers);
+ }
+
+ template <typename Const_Buffers, typename Handler>
+ void async_write_some(const Const_Buffers& buffers, Handler handler)
+ {
+ size_t bytes_transferred = write_some(buffers);
+ asio::post(get_executor(),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(Handler)(handler),
+ asio::error_code(), bytes_transferred));
+ }
+
+private:
+ asio::io_context& io_context_;
+ enum { max_length = 8192 };
+ char data_[max_length];
+ size_t length_;
+ size_t position_;
+ size_t next_write_length_;
+};
+
+static const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+static char mutable_write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void test_2_arg_zero_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+
+ size_t bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == 0);
+}
+
+void test_2_arg_const_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_2_arg_mutable_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+}
+
+void test_2_arg_vector_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_3_arg_nothrow_zero_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == 0);
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_const_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_mutable_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_3_arg_nothrow_vector_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+bool old_style_transfer_all(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec;
+}
+
+size_t short_transfer(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec ? 0 : 3;
+}
+
+void test_3_arg_const_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_3_arg_mutable_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+}
+
+void test_3_arg_vector_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write(s, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_4_arg_const_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_mutable_buffer_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_vector_buffers_write()
+{
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write(s, buffers, short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void async_write_handler(const asio::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!e);
+ ASIO_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_3_arg_const_buffer_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_3_arg_mutable_buffer_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+}
+
+void test_3_arg_boost_array_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ boost::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_3_arg_std_array_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_3_arg_vector_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_3_arg_streambuf_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb;
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ bool called = false;
+ asio::async_write(s, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ int i = asio::async_write(s, sb, archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_4_arg_const_buffer_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_4_arg_mutable_buffer_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_4_arg_boost_array_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ boost::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_4_arg_std_array_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_4_arg_vector_buffers_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ bool called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write(s, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+void test_4_arg_streambuf_async_write()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_stream s(ioc);
+ asio::streambuf sb;
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ bool called = false;
+ asio::async_write(s, sb, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 50));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write(s, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write(s, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write(s, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ int i = asio::async_write(s, sb, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(buffers, sizeof(write_data)));
+}
+
+ASIO_TEST_SUITE
+(
+ "write",
+ ASIO_TEST_CASE(test_2_arg_zero_buffers_write)
+ ASIO_TEST_CASE(test_2_arg_const_buffer_write)
+ ASIO_TEST_CASE(test_2_arg_mutable_buffer_write)
+ ASIO_TEST_CASE(test_2_arg_vector_buffers_write)
+ ASIO_TEST_CASE(test_3_arg_nothrow_zero_buffers_write)
+ ASIO_TEST_CASE(test_3_arg_nothrow_const_buffer_write)
+ ASIO_TEST_CASE(test_3_arg_nothrow_mutable_buffer_write)
+ ASIO_TEST_CASE(test_3_arg_nothrow_vector_buffers_write)
+ ASIO_TEST_CASE(test_3_arg_const_buffer_write)
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_write)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_write)
+ ASIO_TEST_CASE(test_4_arg_const_buffer_write)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_write)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_write)
+ ASIO_TEST_CASE(test_3_arg_const_buffer_async_write)
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_async_write)
+ ASIO_TEST_CASE(test_3_arg_boost_array_buffers_async_write)
+ ASIO_TEST_CASE(test_3_arg_std_array_buffers_async_write)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_async_write)
+ ASIO_TEST_CASE(test_3_arg_streambuf_async_write)
+ ASIO_TEST_CASE(test_4_arg_const_buffer_async_write)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_async_write)
+ ASIO_TEST_CASE(test_4_arg_boost_array_buffers_async_write)
+ ASIO_TEST_CASE(test_4_arg_std_array_buffers_async_write)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_async_write)
+ ASIO_TEST_CASE(test_4_arg_streambuf_async_write)
+)
diff --git a/3rdparty/asio/src/tests/unit/write_at.cpp b/3rdparty/asio/src/tests/unit/write_at.cpp
new file mode 100644
index 00000000000..a8e55e87d90
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/write_at.cpp
@@ -0,0 +1,7554 @@
+//
+// write_at.cpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2016 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/write_at.hpp"
+
+#include <cstring>
+#include "archetypes/async_result.hpp"
+#include "asio/io_context.hpp"
+#include "asio/post.hpp"
+#include "asio/streambuf.hpp"
+#include "unit_test.hpp"
+
+#if defined(ASIO_HAS_BOOST_BIND)
+# include <boost/bind.hpp>
+#else // defined(ASIO_HAS_BOOST_BIND)
+# include <functional>
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+#include <boost/array.hpp>
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(ASIO_HAS_STD_ARRAY)
+
+using namespace std; // For memcmp, memcpy and memset.
+
+class test_random_access_device
+{
+public:
+ typedef asio::io_context::executor_type executor_type;
+
+ test_random_access_device(asio::io_context& io_context)
+ : io_context_(io_context),
+ length_(max_length),
+ next_write_length_(max_length)
+ {
+ memset(data_, 0, max_length);
+ }
+
+ executor_type get_executor() ASIO_NOEXCEPT
+ {
+ return io_context_.get_executor();
+ }
+
+ void reset()
+ {
+ memset(data_, 0, max_length);
+ next_write_length_ = max_length;
+ }
+
+ void next_write_length(size_t length)
+ {
+ next_write_length_ = length;
+ }
+
+ template <typename Iterator>
+ bool check_buffers(asio::uint64_t offset,
+ Iterator begin, Iterator end, size_t length)
+ {
+ if (offset + length > max_length)
+ return false;
+
+ Iterator iter = begin;
+ size_t checked_length = 0;
+ for (; iter != end && checked_length < length; ++iter)
+ {
+ size_t buffer_length = asio::buffer_size(*iter);
+ if (buffer_length > length - checked_length)
+ buffer_length = length - checked_length;
+ if (memcmp(data_ + offset + checked_length,
+ iter->data(), buffer_length) != 0)
+ return false;
+ checked_length += buffer_length;
+ }
+
+ return true;
+ }
+
+ template <typename Const_Buffers>
+ bool check_buffers(asio::uint64_t offset,
+ const Const_Buffers& buffers, size_t length)
+ {
+ return check_buffers(offset, asio::buffer_sequence_begin(buffers),
+ asio::buffer_sequence_end(buffers), length);
+ }
+
+ template <typename Const_Buffers>
+ size_t write_some_at(asio::uint64_t offset,
+ const Const_Buffers& buffers)
+ {
+ return asio::buffer_copy(
+ asio::buffer(data_, length_) + offset,
+ buffers, next_write_length_);
+ }
+
+ template <typename Const_Buffers>
+ size_t write_some_at(asio::uint64_t offset,
+ const Const_Buffers& buffers, asio::error_code& ec)
+ {
+ ec = asio::error_code();
+ return write_some_at(offset, buffers);
+ }
+
+ template <typename Const_Buffers, typename Handler>
+ void async_write_some_at(asio::uint64_t offset,
+ const Const_Buffers& buffers, Handler handler)
+ {
+ size_t bytes_transferred = write_some_at(offset, buffers);
+ asio::post(get_executor(),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(Handler)(handler),
+ asio::error_code(), bytes_transferred));
+ }
+
+private:
+ asio::io_context& io_context_;
+ enum { max_length = 8192 };
+ char data_[max_length];
+ size_t length_;
+ size_t next_write_length_;
+};
+
+static const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+static char mutable_write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void test_3_arg_const_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_3_arg_mutable_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+}
+
+void test_3_arg_vector_buffers_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_nothrow_const_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_nothrow_mutable_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_4_arg_nothrow_vector_buffers_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+bool old_style_transfer_all(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec;
+}
+
+size_t short_transfer(const asio::error_code& ec,
+ size_t /*bytes_transferred*/)
+{
+ return !!ec ? 0 : 3;
+}
+
+void test_4_arg_const_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_mutable_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+}
+
+void test_4_arg_vector_buffers_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all());
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42));
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1));
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10));
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42));
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 0, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = asio::write_at(s, 1234, buffers, short_transfer);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_const_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_5_arg_mutable_buffer_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ ASIO_CHECK(!error);
+}
+
+void test_5_arg_vector_buffers_write_at()
+{
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ asio::error_code error;
+ size_t bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_all(), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(1), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_at_least(42), error);
+ ASIO_CHECK(bytes_transferred == 50);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(1), error);
+ ASIO_CHECK(bytes_transferred == 1);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(10), error);
+ ASIO_CHECK(bytes_transferred == 10);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ asio::transfer_exactly(42), error);
+ ASIO_CHECK(bytes_transferred == 42);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = asio::error_code();
+ bytes_transferred = asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ ASIO_CHECK(bytes_transferred == sizeof(write_data));
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ ASIO_CHECK(!error);
+}
+
+void async_write_handler(const asio::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ ASIO_CHECK(!e);
+ ASIO_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_4_arg_const_buffer_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_mutable_buffer_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_boost_array_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ boost::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_4_arg_std_array_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_4_arg_vector_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_streambuf_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb;
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ bool called = false;
+ asio::async_write_at(s, 0, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ int i = asio::async_write_at(s, 0, sb,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_const_buffer_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_mutable_buffer_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::mutable_buffer buffers
+ = asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(mutable_write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_boost_array_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_BOOST_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ boost::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_BOOST_ARRAY)
+}
+
+void test_5_arg_std_array_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+#if defined(ASIO_HAS_STD_ARRAY)
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::array<asio::const_buffer, 2> buffers = { {
+ asio::buffer(write_data, 32),
+ asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+#endif // defined(ASIO_HAS_STD_ARRAY)
+}
+
+void test_5_arg_vector_buffers_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ std::vector<asio::const_buffer> buffers;
+ buffers.push_back(asio::buffer(write_data, 32));
+ buffers.push_back(asio::buffer(write_data) + 32);
+
+ s.reset();
+ bool called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, buffers, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ int i = asio::async_write_at(s, 0, buffers, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_streambuf_async_write_at()
+{
+#if defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = boost;
+#else // defined(ASIO_HAS_BOOST_BIND)
+ namespace bindns = std;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+#endif // defined(ASIO_HAS_BOOST_BIND)
+
+ asio::io_context ioc;
+ test_random_access_device s(ioc);
+ asio::streambuf sb;
+ asio::const_buffer buffers
+ = asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ bool called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_all(),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_at_least(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 50, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(1),
+ bindns::bind(async_write_handler,
+ _1, _2, 1, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(10),
+ bindns::bind(async_write_handler,
+ _1, _2, 10, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb,
+ asio::transfer_exactly(42),
+ bindns::bind(async_write_handler,
+ _1, _2, 42, &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb, old_style_transfer_all,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 0, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ called = false;
+ asio::async_write_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 0, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(1);
+ called = false;
+ asio::async_write_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 0, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ s.next_write_length(10);
+ called = false;
+ asio::async_write_at(s, 1234, sb, short_transfer,
+ bindns::bind(async_write_handler,
+ _1, _2, sizeof(write_data), &called));
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(called);
+ ASIO_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ sb.consume(sb.size());
+ sb.sputn(write_data, sizeof(write_data));
+ int i = asio::async_write_at(s, 0, sb, short_transfer,
+ archetypes::lazy_handler());
+ ASIO_CHECK(i == 42);
+ ioc.restart();
+ ioc.run();
+ ASIO_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+ASIO_TEST_SUITE
+(
+ "write_at",
+ ASIO_TEST_CASE(test_3_arg_const_buffer_write_at)
+ ASIO_TEST_CASE(test_3_arg_mutable_buffer_write_at)
+ ASIO_TEST_CASE(test_3_arg_vector_buffers_write_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_const_buffer_write_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_mutable_buffer_write_at)
+ ASIO_TEST_CASE(test_4_arg_nothrow_vector_buffers_write_at)
+ ASIO_TEST_CASE(test_4_arg_const_buffer_write_at)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_write_at)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_write_at)
+ ASIO_TEST_CASE(test_5_arg_const_buffer_write_at)
+ ASIO_TEST_CASE(test_5_arg_mutable_buffer_write_at)
+ ASIO_TEST_CASE(test_5_arg_vector_buffers_write_at)
+ ASIO_TEST_CASE(test_4_arg_const_buffer_async_write_at)
+ ASIO_TEST_CASE(test_4_arg_mutable_buffer_async_write_at)
+ ASIO_TEST_CASE(test_4_arg_boost_array_buffers_async_write_at)
+ ASIO_TEST_CASE(test_4_arg_std_array_buffers_async_write_at)
+ ASIO_TEST_CASE(test_4_arg_vector_buffers_async_write_at)
+ ASIO_TEST_CASE(test_4_arg_streambuf_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_const_buffer_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_mutable_buffer_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_boost_array_buffers_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_std_array_buffers_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_vector_buffers_async_write_at)
+ ASIO_TEST_CASE(test_5_arg_streambuf_async_write_at)
+)
diff --git a/3rdparty/asio/src/tools/handlerviz.pl b/3rdparty/asio/src/tools/handlerviz.pl
new file mode 100644
index 00000000000..06249a2cdea
--- /dev/null
+++ b/3rdparty/asio/src/tools/handlerviz.pl
@@ -0,0 +1,299 @@
+#!/usr/bin/perl -w
+#
+# handlerviz.pl
+# ~~~~~~~~~~~~~
+#
+# A visualisation tool for post-processing the debug output generated by
+# Asio-based programs. Programs write this output to the standard error stream
+# when compiled with the define `ASIO_ENABLE_HANDLER_TRACKING'.
+#
+# This tool generates output intended for use with the GraphViz tool `dot'. For
+# example, to convert output to a PNG image, use:
+#
+# perl handlerviz.pl < output.txt | dot -Tpng > output.png
+#
+# To convert to a PDF file, use:
+#
+# perl handlerviz.pl < output.txt | dot -Tpdf > output.pdf
+#
+# Copyright (c) 2011 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)
+#
+
+use strict;
+
+my %nodes = ();
+my @edges = ();
+my %anon_nodes = ();
+my $anon_id = 0;
+my %all_nodes = ();
+
+#-------------------------------------------------------------------------------
+# Parse the debugging output and populate the nodes and edges.
+
+sub parse_debug_output()
+{
+ while (my $line = <>)
+ {
+ chomp($line);
+
+ if ($line =~ /\@asio\|([^|]*)\|([^|]*)\|(.*)$/)
+ {
+ my $timestamp = $1;
+ my $action = $2;
+ my $description = $3;
+
+ # Handler creation.
+ if ($action =~ /^([0-9]+)\*([0-9]+)$/)
+ {
+ my $begin = $1;
+ my $end = $2;
+ my $label = $description;
+ $label =~ s/\./\\n/g;
+
+ if ($begin eq "0")
+ {
+ $begin = "a" . $anon_id++;
+ $anon_nodes{$begin} = $timestamp;
+ $all_nodes{"$timestamp-$begin"} = $begin;
+ }
+
+ my %edge = ( begin=>$begin, end=>$end, label=>$label );
+ push(@edges, \%edge);
+ }
+
+ # Begin handler invocation.
+ elsif ($action =~ /^>([0-9]+)$/)
+ {
+ my %new_node = ( label=>$description, entry=>$timestamp );
+ $new_node{content} = ();
+ $nodes{$1} = \%new_node;
+ $all_nodes{"$timestamp-$1"} = $1;
+ }
+
+ # End handler invocation.
+ elsif ($action =~ /^<([0-9]+)$/)
+ {
+ $nodes{$1}->{exit} = $timestamp;
+ }
+
+ # Handler threw exception.
+ elsif ($action =~ /^!([0-9]+)$/)
+ {
+ push(@{$nodes{$1}->{content}}, "exception");
+ }
+
+ # Handler was destroyed without being invoked.
+ elsif ($action =~ /^~([0-9]+)$/)
+ {
+ my %new_node = ( label=>"$timestamp destroyed" );
+ $new_node{content} = ();
+ $nodes{$1} = \%new_node;
+ $all_nodes{"$timestamp-$1"} = $1;
+ }
+
+ # Handler performed some operation.
+ elsif ($action =~ /^([0-9]+)$/)
+ {
+ if ($1 eq "0")
+ {
+ my $id = "a" . $anon_id++;
+ $anon_nodes{$id} = "$timestamp\\l$description";
+ $all_nodes{"$timestamp-$id"} = $id;
+ }
+ else
+ {
+ push(@{$nodes{$1}->{content}}, "$description");
+ }
+ }
+ }
+ }
+}
+
+#-------------------------------------------------------------------------------
+# Helper function to convert a string to escaped HTML text.
+
+sub escape($)
+{
+ my $text = shift;
+ $text =~ s/&/\&amp\;/g;
+ $text =~ s/</\&lt\;/g;
+ $text =~ s/>/\&gt\;/g;
+ $text =~ s/\t/ /g;
+ return $text;
+}
+
+#-------------------------------------------------------------------------------
+# Templates for dot output.
+
+my $graph_header = <<"EOF";
+/* Generated by asioviz.pl */
+digraph G
+{
+graph [ nodesep="1" ];
+node [ shape="box", fontsize="9" ];
+edge [ arrowtail="dot", fontsize="9" ];
+EOF
+
+my $graph_footer = <<"EOF";
+}
+EOF
+
+my $node_header = <<"EOF";
+"%name%"
+[
+label=<<table border="0" cellspacing="0">
+<tr><td align="left" bgcolor="gray" border="0">%label%</td></tr>
+EOF
+
+my $node_footer = <<"EOF";
+</table>>
+]
+EOF
+
+my $node_content = <<"EOF";
+<tr><td align="left" bgcolor="white" border="0">
+<font face="mono" point-size="9">%content%</font>
+</td></tr>
+EOF
+
+my $anon_nodes_header = <<"EOF";
+{
+node [ shape="record" ];
+EOF
+
+my $anon_nodes_footer = <<"EOF";
+}
+EOF
+
+my $anon_node = <<"EOF";
+"%name%" [ label="%label%", color="gray" ];
+EOF
+
+my $edges_header = <<"EOF";
+{
+edge [ style="dashed", arrowhead="open", weight="100" ];
+EOF
+
+my $edges_footer = <<"EOF";
+}
+EOF
+
+my $edge = <<"EOF";
+"%begin%" -> "%end%" [ label="%label%" ]
+EOF
+
+my $node_order_header = <<"EOF";
+{
+edge [ style="invis", weight="1" ];
+EOF
+
+my $node_order_footer = <<"EOF";
+}
+EOF
+
+my $node_order = <<"EOF";
+"%begin%" -> "%end%"
+EOF
+
+#-------------------------------------------------------------------------------
+# Generate dot output from the nodes and edges.
+
+sub print_nodes()
+{
+ foreach my $name (sort keys %nodes)
+ {
+ my $node = $nodes{$name};
+ my $entry = $node->{entry};
+ my $exit = $node->{exit};
+ my $label = escape($node->{label});
+ my $header = $node_header;
+ $header =~ s/%name%/$name/g;
+ $header =~ s/%label%/$label/g;
+ print($header);
+
+ my $line = $node_content;
+ my $content = $entry . " + " . sprintf("%.6f", $exit - $entry) . "s";
+ $line =~ s/%content%/$content/g;
+ print($line);
+
+ foreach my $content (@{$node->{content}})
+ {
+ $content = escape($content);
+ $content = " " if length($content) == 0;
+ my $line = $node_content;
+ $line =~ s/%content%/$content/g;
+ print($line);
+ }
+
+ print($node_footer);
+ }
+}
+
+sub print_anon_nodes()
+{
+ print($anon_nodes_header);
+ foreach my $name (sort keys %anon_nodes)
+ {
+ my $label = $anon_nodes{$name};
+ my $line = $anon_node;
+ $line =~ s/%name%/$name/g;
+ $line =~ s/%label%/$label/g;
+ print($line);
+ }
+ print($edges_footer);
+}
+
+sub print_edges()
+{
+ print($edges_header);
+ foreach my $e (@edges)
+ {
+ my $begin = $e->{begin};
+ my $end = $e->{end};
+ my $label = $e->{label};
+ my $line = $edge;
+ $line =~ s/%begin%/$begin/g;
+ $line =~ s/%end%/$end/g;
+ $line =~ s/%label%/$label/g;
+ print($line);
+ }
+ print($edges_footer);
+}
+
+sub print_node_order()
+{
+ my $prev = "";
+ print($node_order_header);
+ foreach my $name (sort keys %all_nodes)
+ {
+ if ($prev ne "")
+ {
+ my $begin = $prev;
+ my $end = $all_nodes{$name};
+ my $line = $node_order;
+ $line =~ s/%begin%/$begin/g;
+ $line =~ s/%end%/$end/g;
+ print($line);
+ }
+ $prev = $all_nodes{$name};
+ }
+ print($node_order_footer);
+}
+
+sub generate_dot()
+{
+ print($graph_header);
+ print_nodes();
+ print_anon_nodes();
+ print_edges();
+ print_node_order();
+ print($graph_footer);
+}
+
+#-------------------------------------------------------------------------------
+
+parse_debug_output();
+generate_dot();