summaryrefslogtreecommitdiff
path: root/boost/asio
diff options
context:
space:
mode:
Diffstat (limited to 'boost/asio')
-rw-r--r--boost/asio/associated_allocator.hpp133
-rw-r--r--boost/asio/associated_executor.hpp151
-rw-r--r--boost/asio/async_result.hpp169
-rw-r--r--boost/asio/basic_datagram_socket.hpp187
-rw-r--r--boost/asio/basic_deadline_timer.hpp178
-rw-r--r--boost/asio/basic_io_object.hpp114
-rw-r--r--boost/asio/basic_raw_socket.hpp186
-rw-r--r--boost/asio/basic_seq_packet_socket.hpp141
-rw-r--r--boost/asio/basic_serial_port.hpp89
-rw-r--r--boost/asio/basic_signal_set.hpp81
-rw-r--r--boost/asio/basic_socket.hpp456
-rw-r--r--boost/asio/basic_socket_acceptor.hpp1061
-rw-r--r--boost/asio/basic_socket_iostream.hpp238
-rw-r--r--boost/asio/basic_socket_streambuf.hpp682
-rw-r--r--boost/asio/basic_stream_socket.hpp161
-rw-r--r--boost/asio/basic_streambuf.hpp113
-rw-r--r--boost/asio/basic_streambuf_fwd.hpp3
-rw-r--r--boost/asio/basic_waitable_timer.hpp282
-rw-r--r--boost/asio/bind_executor.hpp613
-rw-r--r--boost/asio/buffer.hpp2289
-rw-r--r--boost/asio/buffered_read_stream.hpp39
-rw-r--r--boost/asio/buffered_stream.hpp30
-rw-r--r--boost/asio/buffered_write_stream.hpp39
-rw-r--r--boost/asio/buffers_iterator.hpp80
-rw-r--r--boost/asio/connect.hpp686
-rw-r--r--boost/asio/coroutine.hpp12
-rw-r--r--boost/asio/datagram_socket_service.hpp156
-rw-r--r--boost/asio/deadline_timer_service.hpp36
-rw-r--r--boost/asio/defer.hpp109
-rw-r--r--boost/asio/detail/addressof.hpp40
-rw-r--r--boost/asio/detail/bind_handler.hpp479
-rw-r--r--boost/asio/detail/buffer_sequence_adapter.hpp261
-rw-r--r--boost/asio/detail/call_stack.hpp2
-rw-r--r--boost/asio/detail/chrono.hpp68
-rw-r--r--boost/asio/detail/completion_handler.hpp12
-rw-r--r--boost/asio/detail/concurrency_hint.hpp94
-rw-r--r--boost/asio/detail/conditionally_enabled_event.hpp114
-rw-r--r--boost/asio/detail/conditionally_enabled_mutex.hpp151
-rw-r--r--boost/asio/detail/config.hpp323
-rw-r--r--boost/asio/detail/consuming_buffers.hpp450
-rw-r--r--boost/asio/detail/cstddef.hpp33
-rw-r--r--boost/asio/detail/cstdint.hpp14
-rw-r--r--boost/asio/detail/deadline_timer_service.hpp77
-rw-r--r--boost/asio/detail/descriptor_ops.hpp4
-rw-r--r--boost/asio/detail/descriptor_read_op.hpp23
-rw-r--r--boost/asio/detail/descriptor_write_op.hpp23
-rw-r--r--boost/asio/detail/dev_poll_reactor.hpp28
-rw-r--r--boost/asio/detail/epoll_reactor.hpp39
-rw-r--r--boost/asio/detail/executor_op.hpp86
-rw-r--r--boost/asio/detail/functional.hpp (renamed from boost/asio/detail/function.hpp)18
-rw-r--r--boost/asio/detail/gcc_arm_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_hppa_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_sync_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_x86_fenced_block.hpp2
-rw-r--r--boost/asio/detail/global.hpp54
-rw-r--r--boost/asio/detail/handler_alloc_helpers.hpp159
-rw-r--r--boost/asio/detail/handler_cont_helpers.hpp2
-rw-r--r--boost/asio/detail/handler_invoke_helpers.hpp2
-rw-r--r--boost/asio/detail/handler_tracking.hpp97
-rw-r--r--boost/asio/detail/handler_type_requirements.hpp150
-rw-r--r--boost/asio/detail/handler_work.hpp97
-rw-r--r--boost/asio/detail/impl/buffer_sequence_adapter.ipp10
-rw-r--r--boost/asio/detail/impl/descriptor_ops.ipp23
-rw-r--r--boost/asio/detail/impl/dev_poll_reactor.hpp19
-rw-r--r--boost/asio/detail/impl/dev_poll_reactor.ipp45
-rw-r--r--boost/asio/detail/impl/epoll_reactor.hpp19
-rw-r--r--boost/asio/detail/impl/epoll_reactor.ipp164
-rw-r--r--boost/asio/detail/impl/handler_tracking.ipp105
-rw-r--r--boost/asio/detail/impl/kqueue_reactor.hpp23
-rw-r--r--boost/asio/detail/impl/kqueue_reactor.ipp88
-rw-r--r--boost/asio/detail/impl/null_event.ipp76
-rw-r--r--boost/asio/detail/impl/posix_event.ipp12
-rw-r--r--boost/asio/detail/impl/posix_thread.ipp10
-rw-r--r--boost/asio/detail/impl/reactive_descriptor_service.ipp19
-rw-r--r--boost/asio/detail/impl/reactive_serial_port_service.ipp11
-rw-r--r--boost/asio/detail/impl/reactive_socket_service_base.ipp37
-rw-r--r--boost/asio/detail/impl/resolver_service_base.ipp82
-rw-r--r--boost/asio/detail/impl/scheduler.ipp (renamed from boost/asio/detail/impl/task_io_service.ipp)235
-rw-r--r--boost/asio/detail/impl/select_reactor.hpp19
-rw-r--r--boost/asio/detail/impl/select_reactor.ipp65
-rw-r--r--boost/asio/detail/impl/service_registry.hpp64
-rw-r--r--boost/asio/detail/impl/service_registry.ipp67
-rw-r--r--boost/asio/detail/impl/signal_set_service.ipp56
-rw-r--r--boost/asio/detail/impl/socket_ops.ipp153
-rw-r--r--boost/asio/detail/impl/strand_executor_service.hpp181
-rw-r--r--boost/asio/detail/impl/strand_executor_service.ipp126
-rw-r--r--boost/asio/detail/impl/strand_service.hpp24
-rw-r--r--boost/asio/detail/impl/strand_service.ipp27
-rw-r--r--boost/asio/detail/impl/task_io_service.hpp80
-rw-r--r--boost/asio/detail/impl/timer_queue_ptime.ipp15
-rw-r--r--boost/asio/detail/impl/win_event.ipp5
-rw-r--r--boost/asio/detail/impl/win_iocp_handle_service.ipp44
-rw-r--r--boost/asio/detail/impl/win_iocp_io_context.hpp (renamed from boost/asio/detail/impl/win_iocp_io_service.hpp)71
-rw-r--r--boost/asio/detail/impl/win_iocp_io_context.ipp (renamed from boost/asio/detail/impl/win_iocp_io_service.ipp)112
-rw-r--r--boost/asio/detail/impl/win_iocp_serial_port_service.ipp7
-rw-r--r--boost/asio/detail/impl/win_iocp_socket_service_base.ipp90
-rw-r--r--boost/asio/detail/impl/win_object_handle_service.ipp36
-rw-r--r--boost/asio/detail/impl/win_thread.ipp7
-rw-r--r--boost/asio/detail/impl/win_tss_ptr.ipp4
-rw-r--r--boost/asio/detail/impl/winrt_ssocket_service_base.ipp55
-rw-r--r--boost/asio/detail/impl/winrt_timer_scheduler.hpp19
-rw-r--r--boost/asio/detail/impl/winrt_timer_scheduler.ipp16
-rw-r--r--boost/asio/detail/io_control.hpp50
-rw-r--r--boost/asio/detail/is_buffer_sequence.hpp241
-rw-r--r--boost/asio/detail/is_executor.hpp128
-rw-r--r--boost/asio/detail/kqueue_reactor.hpp36
-rw-r--r--boost/asio/detail/macos_fenced_block.hpp1
-rw-r--r--boost/asio/detail/memory.hpp41
-rw-r--r--boost/asio/detail/null_event.hpp20
-rw-r--r--boost/asio/detail/null_fenced_block.hpp2
-rw-r--r--boost/asio/detail/null_global.hpp61
-rw-r--r--boost/asio/detail/null_reactor.hpp17
-rw-r--r--boost/asio/detail/null_socket_service.hpp46
-rw-r--r--boost/asio/detail/null_thread.hpp6
-rw-r--r--boost/asio/detail/object_pool.hpp25
-rw-r--r--boost/asio/detail/operation.hpp4
-rw-r--r--boost/asio/detail/pop_options.hpp4
-rw-r--r--boost/asio/detail/posix_event.hpp33
-rw-r--r--boost/asio/detail/posix_global.hpp82
-rw-r--r--boost/asio/detail/posix_thread.hpp4
-rw-r--r--boost/asio/detail/push_options.hpp9
-rw-r--r--boost/asio/detail/reactive_descriptor_service.hpp104
-rw-r--r--boost/asio/detail/reactive_null_buffers_op.hpp14
-rw-r--r--boost/asio/detail/reactive_serial_port_service.hpp16
-rw-r--r--boost/asio/detail/reactive_socket_accept_op.hpp119
-rw-r--r--boost/asio/detail/reactive_socket_connect_op.hpp19
-rw-r--r--boost/asio/detail/reactive_socket_recv_op.hpp26
-rw-r--r--boost/asio/detail/reactive_socket_recvfrom_op.hpp19
-rw-r--r--boost/asio/detail/reactive_socket_recvmsg_op.hpp21
-rw-r--r--boost/asio/detail/reactive_socket_send_op.hpp34
-rw-r--r--boost/asio/detail/reactive_socket_sendto_op.hpp21
-rw-r--r--boost/asio/detail/reactive_socket_service.hpp128
-rw-r--r--boost/asio/detail/reactive_socket_service_base.hpp129
-rw-r--r--boost/asio/detail/reactive_wait_op.hpp92
-rw-r--r--boost/asio/detail/reactor.hpp2
-rw-r--r--boost/asio/detail/reactor_fwd.hpp2
-rw-r--r--boost/asio/detail/reactor_op.hpp8
-rw-r--r--boost/asio/detail/recycling_allocator.hpp106
-rw-r--r--boost/asio/detail/resolve_endpoint_op.hpp47
-rw-r--r--boost/asio/detail/resolve_op.hpp96
-rw-r--r--boost/asio/detail/resolve_query_op.hpp136
-rw-r--r--boost/asio/detail/resolver_service.hpp58
-rw-r--r--boost/asio/detail/resolver_service_base.hpp47
-rw-r--r--boost/asio/detail/scheduler.hpp (renamed from boost/asio/detail/task_io_service.hpp)100
-rw-r--r--boost/asio/detail/scheduler_operation.hpp (renamed from boost/asio/detail/task_io_service_operation.hpp)34
-rw-r--r--boost/asio/detail/scheduler_thread_info.hpp (renamed from boost/asio/detail/task_io_service_thread_info.hpp)18
-rw-r--r--boost/asio/detail/scoped_ptr.hpp8
-rw-r--r--boost/asio/detail/select_reactor.hpp40
-rw-r--r--boost/asio/detail/service_registry.hpp86
-rw-r--r--boost/asio/detail/shared_ptr.hpp40
-rw-r--r--boost/asio/detail/signal_handler.hpp12
-rw-r--r--boost/asio/detail/signal_set_service.hpp25
-rw-r--r--boost/asio/detail/socket_ops.hpp13
-rw-r--r--boost/asio/detail/socket_types.hpp6
-rw-r--r--boost/asio/detail/solaris_fenced_block.hpp1
-rw-r--r--boost/asio/detail/std_global.hpp72
-rw-r--r--boost/asio/detail/std_thread.hpp6
-rw-r--r--boost/asio/detail/strand_executor_service.hpp140
-rw-r--r--boost/asio/detail/strand_service.hpp18
-rw-r--r--boost/asio/detail/string_view.hpp47
-rw-r--r--boost/asio/detail/thread.hpp12
-rw-r--r--boost/asio/detail/thread_context.hpp44
-rw-r--r--boost/asio/detail/thread_group.hpp91
-rw-r--r--boost/asio/detail/thread_info_base.hpp11
-rw-r--r--boost/asio/detail/timer_queue.hpp29
-rw-r--r--boost/asio/detail/timer_queue_ptime.hpp14
-rw-r--r--boost/asio/detail/timer_scheduler.hpp2
-rw-r--r--boost/asio/detail/timer_scheduler_fwd.hpp2
-rw-r--r--boost/asio/detail/type_traits.hpp22
-rw-r--r--boost/asio/detail/variadic_templates.hpp98
-rw-r--r--boost/asio/detail/wait_handler.hpp12
-rw-r--r--boost/asio/detail/weak_ptr.hpp40
-rw-r--r--boost/asio/detail/win_event.hpp21
-rw-r--r--boost/asio/detail/win_fenced_block.hpp1
-rw-r--r--boost/asio/detail/win_global.hpp75
-rw-r--r--boost/asio/detail/win_iocp_handle_read_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_handle_service.hpp39
-rw-r--r--boost/asio/detail/win_iocp_handle_write_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_io_context.hpp (renamed from boost/asio/detail/win_iocp_io_service.hpp)75
-rw-r--r--boost/asio/detail/win_iocp_null_buffers_op.hpp14
-rw-r--r--boost/asio/detail/win_iocp_operation.hpp13
-rw-r--r--boost/asio/detail/win_iocp_overlapped_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_overlapped_ptr.hpp25
-rw-r--r--boost/asio/detail/win_iocp_serial_port_service.hpp16
-rw-r--r--boost/asio/detail/win_iocp_socket_accept_op.hpp140
-rw-r--r--boost/asio/detail/win_iocp_socket_connect_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_socket_recv_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_socket_recvfrom_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_socket_recvmsg_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_socket_send_op.hpp10
-rw-r--r--boost/asio/detail/win_iocp_socket_service.hpp135
-rw-r--r--boost/asio/detail/win_iocp_socket_service_base.hpp153
-rw-r--r--boost/asio/detail/win_iocp_wait_op.hpp123
-rw-r--r--boost/asio/detail/win_object_handle_service.hpp21
-rw-r--r--boost/asio/detail/win_thread.hpp4
-rw-r--r--boost/asio/detail/winapp_thread.hpp (renamed from boost/asio/detail/winapi_thread.hpp)44
-rw-r--r--boost/asio/detail/wince_thread.hpp126
-rw-r--r--boost/asio/detail/winrt_async_manager.hpp26
-rw-r--r--boost/asio/detail/winrt_resolve_op.hpp25
-rw-r--r--boost/asio/detail/winrt_resolver_service.hpp65
-rw-r--r--boost/asio/detail/winrt_socket_connect_op.hpp12
-rw-r--r--boost/asio/detail/winrt_socket_recv_op.hpp10
-rw-r--r--boost/asio/detail/winrt_socket_send_op.hpp10
-rw-r--r--boost/asio/detail/winrt_ssocket_service.hpp22
-rw-r--r--boost/asio/detail/winrt_ssocket_service_base.hpp32
-rw-r--r--boost/asio/detail/winrt_timer_scheduler.hpp20
-rw-r--r--boost/asio/detail/winrt_utils.hpp6
-rw-r--r--boost/asio/detail/work_dispatcher.hpp74
-rw-r--r--boost/asio/dispatch.hpp110
-rw-r--r--boost/asio/error.hpp16
-rw-r--r--boost/asio/execution_context.hpp413
-rw-r--r--boost/asio/executor.hpp343
-rw-r--r--boost/asio/executor_work_guard.hpp171
-rw-r--r--boost/asio/generic/detail/impl/endpoint.ipp3
-rw-r--r--boost/asio/handler_invoke_hook.hpp6
-rw-r--r--boost/asio/handler_type.hpp82
-rw-r--r--boost/asio/high_resolution_timer.hpp25
-rw-r--r--boost/asio/impl/buffered_read_stream.hpp99
-rw-r--r--boost/asio/impl/buffered_write_stream.hpp109
-rw-r--r--boost/asio/impl/connect.hpp666
-rw-r--r--boost/asio/impl/defer.hpp79
-rw-r--r--boost/asio/impl/dispatch.hpp80
-rw-r--r--boost/asio/impl/execution_context.hpp109
-rw-r--r--boost/asio/impl/execution_context.ipp84
-rw-r--r--boost/asio/impl/executor.hpp388
-rw-r--r--boost/asio/impl/executor.ipp (renamed from boost/asio/ssl/basic_context.hpp)28
-rw-r--r--boost/asio/impl/handler_alloc_hook.ipp37
-rw-r--r--boost/asio/impl/io_context.hpp345
-rw-r--r--boost/asio/impl/io_context.ipp176
-rw-r--r--boost/asio/impl/io_service.hpp156
-rw-r--r--boost/asio/impl/io_service.ipp157
-rw-r--r--boost/asio/impl/post.hpp79
-rw-r--r--boost/asio/impl/read.hpp718
-rw-r--r--boost/asio/impl/read_at.hpp514
-rw-r--r--boost/asio/impl/read_until.hpp763
-rw-r--r--boost/asio/impl/serial_port_base.ipp58
-rw-r--r--boost/asio/impl/spawn.hpp308
-rw-r--r--boost/asio/impl/src.hpp14
-rw-r--r--boost/asio/impl/system_context.hpp (renamed from boost/asio/ssl/context_service.hpp)26
-rw-r--r--boost/asio/impl/system_context.ipp75
-rw-r--r--boost/asio/impl/system_executor.hpp87
-rw-r--r--boost/asio/impl/thread_pool.hpp129
-rw-r--r--boost/asio/impl/thread_pool.ipp78
-rw-r--r--boost/asio/impl/use_future.hpp947
-rw-r--r--boost/asio/impl/write.hpp805
-rw-r--r--boost/asio/impl/write_at.hpp581
-rw-r--r--boost/asio/io_context.hpp878
-rw-r--r--boost/asio/io_context_strand.hpp384
-rw-r--r--boost/asio/io_service.hpp747
-rw-r--r--boost/asio/io_service_strand.hpp20
-rw-r--r--boost/asio/ip/address.hpp96
-rw-r--r--boost/asio/ip/address_v4.hpp132
-rw-r--r--boost/asio/ip/address_v4_iterator.hpp164
-rw-r--r--boost/asio/ip/address_v4_range.hpp136
-rw-r--r--boost/asio/ip/address_v6.hpp116
-rw-r--r--boost/asio/ip/address_v6_iterator.hpp185
-rw-r--r--boost/asio/ip/address_v6_range.hpp131
-rw-r--r--boost/asio/ip/bad_address_cast.hpp50
-rw-r--r--boost/asio/ip/basic_endpoint.hpp8
-rw-r--r--boost/asio/ip/basic_resolver.hpp890
-rw-r--r--boost/asio/ip/basic_resolver_entry.hpp25
-rw-r--r--boost/asio/ip/basic_resolver_iterator.hpp128
-rw-r--r--boost/asio/ip/basic_resolver_results.hpp313
-rw-r--r--boost/asio/ip/detail/endpoint.hpp2
-rw-r--r--boost/asio/ip/detail/impl/endpoint.ipp13
-rw-r--r--boost/asio/ip/detail/socket_option.hpp33
-rw-r--r--boost/asio/ip/impl/address.hpp40
-rw-r--r--boost/asio/ip/impl/address.ipp100
-rw-r--r--boost/asio/ip/impl/address_v4.hpp40
-rw-r--r--boost/asio/ip/impl/address_v4.ipp118
-rw-r--r--boost/asio/ip/impl/address_v6.hpp40
-rw-r--r--boost/asio/ip/impl/address_v6.ipp116
-rw-r--r--boost/asio/ip/impl/basic_endpoint.hpp14
-rw-r--r--boost/asio/ip/impl/network_v4.hpp56
-rw-r--r--boost/asio/ip/impl/network_v4.ipp217
-rw-r--r--boost/asio/ip/impl/network_v6.hpp55
-rw-r--r--boost/asio/ip/impl/network_v6.ipp186
-rw-r--r--boost/asio/ip/multicast.hpp14
-rw-r--r--boost/asio/ip/network_v4.hpp263
-rw-r--r--boost/asio/ip/network_v6.hpp237
-rw-r--r--boost/asio/ip/resolver_base.hpp131
-rw-r--r--boost/asio/ip/resolver_query_base.hpp91
-rw-r--r--boost/asio/ip/resolver_service.hpp70
-rw-r--r--boost/asio/ip/tcp.hpp4
-rw-r--r--boost/asio/ip/unicast.hpp4
-rw-r--r--boost/asio/ip/v6_only.hpp4
-rw-r--r--boost/asio/is_executor.hpp48
-rw-r--r--boost/asio/local/connect_pair.hpp42
-rw-r--r--boost/asio/local/detail/impl/endpoint.ipp3
-rw-r--r--boost/asio/packaged_task.hpp128
-rw-r--r--boost/asio/placeholders.hpp30
-rw-r--r--boost/asio/posix/basic_descriptor.hpp182
-rw-r--r--boost/asio/posix/basic_stream_descriptor.hpp28
-rw-r--r--boost/asio/posix/descriptor.hpp646
-rw-r--r--boost/asio/posix/descriptor_base.hpp39
-rw-r--r--boost/asio/posix/stream_descriptor.hpp327
-rw-r--r--boost/asio/posix/stream_descriptor_service.hpp105
-rw-r--r--boost/asio/post.hpp109
-rw-r--r--boost/asio/raw_socket_service.hpp156
-rw-r--r--boost/asio/read.hpp338
-rw-r--r--boost/asio/read_at.hpp17
-rw-r--r--boost/asio/read_until.hpp967
-rw-r--r--boost/asio/seq_packet_socket_service.hpp142
-rw-r--r--boost/asio/serial_port.hpp737
-rw-r--r--boost/asio/serial_port_base.hpp20
-rw-r--r--boost/asio/serial_port_service.hpp84
-rw-r--r--boost/asio/signal_set.hpp423
-rw-r--r--boost/asio/signal_set_service.hpp54
-rw-r--r--boost/asio/socket_acceptor_service.hpp160
-rw-r--r--boost/asio/socket_base.hpp129
-rw-r--r--boost/asio/spawn.hpp105
-rw-r--r--boost/asio/ssl.hpp3
-rw-r--r--boost/asio/ssl/context.hpp93
-rw-r--r--boost/asio/ssl/detail/buffered_handshake_op.hpp48
-rw-r--r--boost/asio/ssl/detail/engine.hpp22
-rw-r--r--boost/asio/ssl/detail/handshake_op.hpp8
-rw-r--r--boost/asio/ssl/detail/impl/engine.ipp45
-rw-r--r--boost/asio/ssl/detail/impl/openssl_init.ipp5
-rw-r--r--boost/asio/ssl/detail/io.hpp53
-rw-r--r--boost/asio/ssl/detail/openssl_init.hpp2
-rw-r--r--boost/asio/ssl/detail/password_callback.hpp12
-rw-r--r--boost/asio/ssl/detail/read_op.hpp10
-rw-r--r--boost/asio/ssl/detail/shutdown_op.hpp8
-rw-r--r--boost/asio/ssl/detail/stream_core.hpp44
-rw-r--r--boost/asio/ssl/detail/verify_callback.hpp8
-rw-r--r--boost/asio/ssl/detail/write_op.hpp10
-rw-r--r--boost/asio/ssl/impl/context.hpp18
-rw-r--r--boost/asio/ssl/impl/context.ipp167
-rw-r--r--boost/asio/ssl/impl/rfc2818_verification.ipp18
-rw-r--r--boost/asio/ssl/old/basic_context.hpp436
-rw-r--r--boost/asio/ssl/old/context_service.hpp176
-rw-r--r--boost/asio/ssl/old/detail/openssl_context_service.hpp396
-rw-r--r--boost/asio/ssl/old/detail/openssl_operation.hpp526
-rw-r--r--boost/asio/ssl/old/detail/openssl_stream_service.hpp573
-rw-r--r--boost/asio/ssl/old/stream.hpp503
-rw-r--r--boost/asio/ssl/old/stream_service.hpp186
-rw-r--r--boost/asio/ssl/rfc2818_verification.hpp18
-rw-r--r--boost/asio/ssl/stream.hpp173
-rw-r--r--boost/asio/ssl/stream_service.hpp42
-rw-r--r--boost/asio/ssl/verify_context.hpp10
-rw-r--r--boost/asio/steady_timer.hpp25
-rw-r--r--boost/asio/strand.hpp382
-rw-r--r--boost/asio/stream_socket_service.hpp142
-rw-r--r--boost/asio/system_context.hpp80
-rw-r--r--boost/asio/system_executor.hpp131
-rw-r--r--boost/asio/system_timer.hpp21
-rw-r--r--boost/asio/thread_pool.hpp234
-rw-r--r--boost/asio/ts/buffer.hpp24
-rw-r--r--boost/asio/ts/executor.hpp35
-rw-r--r--boost/asio/ts/internet.hpp40
-rw-r--r--boost/asio/ts/io_context.hpp20
-rw-r--r--boost/asio/ts/net.hpp26
-rw-r--r--boost/asio/ts/netfwd.hpp199
-rw-r--r--boost/asio/ts/socket.hpp27
-rw-r--r--boost/asio/ts/timer.hpp26
-rw-r--r--boost/asio/use_future.hpp77
-rw-r--r--boost/asio/uses_executor.hpp73
-rw-r--r--boost/asio/version.hpp2
-rw-r--r--boost/asio/wait_traits.hpp17
-rw-r--r--boost/asio/waitable_timer_service.hpp80
-rw-r--r--boost/asio/windows/basic_handle.hpp50
-rw-r--r--boost/asio/windows/basic_object_handle.hpp22
-rw-r--r--boost/asio/windows/basic_random_access_handle.hpp28
-rw-r--r--boost/asio/windows/basic_stream_handle.hpp28
-rw-r--r--boost/asio/windows/object_handle.hpp347
-rw-r--r--boost/asio/windows/object_handle_service.hpp44
-rw-r--r--boost/asio/windows/overlapped_handle.hpp333
-rw-r--r--boost/asio/windows/overlapped_ptr.hpp10
-rw-r--r--boost/asio/windows/random_access_handle.hpp345
-rw-r--r--boost/asio/windows/random_access_handle_service.hpp66
-rw-r--r--boost/asio/windows/stream_handle.hpp329
-rw-r--r--boost/asio/windows/stream_handle_service.hpp64
-rw-r--r--boost/asio/write.hpp331
-rw-r--r--boost/asio/write_at.hpp17
374 files changed, 32894 insertions, 12780 deletions
diff --git a/boost/asio/associated_allocator.hpp b/boost/asio/associated_allocator.hpp
new file mode 100644
index 0000000000..b9ef5a452f
--- /dev/null
+++ b/boost/asio/associated_allocator.hpp
@@ -0,0 +1,133 @@
+//
+// associated_allocator.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
+#define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <memory>
+#include <boost/asio/detail/type_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename>
+struct associated_allocator_check
+{
+ typedef void type;
+};
+
+template <typename T, typename E, typename = void>
+struct associated_allocator_impl
+{
+ typedef E type;
+
+ static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
+ {
+ return e;
+ }
+};
+
+template <typename T, typename E>
+struct associated_allocator_impl<T, E,
+ typename associated_allocator_check<typename T::allocator_type>::type>
+{
+ typedef typename T::allocator_type type;
+
+ static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
+ {
+ return t.get_allocator();
+ }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the allocator associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Allocator shall be a type meeting the Allocator requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c a is an object of type @c
+ * Allocator.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Allocator requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,a) and with return type @c type.
+ */
+template <typename T, typename Allocator = std::allocator<void> >
+struct associated_allocator
+{
+ /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
+ /// Otherwise @c Allocator.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef see_below type;
+#else // defined(GENERATING_DOCUMENTATION)
+ typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+ /// If @c T has a nested type @c allocator_type, returns
+ /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
+ static type get(const T& t,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return detail::associated_allocator_impl<T, Allocator>::get(t, a);
+ }
+};
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_allocator<T>::type
+get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
+{
+ return associated_allocator<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
+ */
+template <typename T, typename Allocator>
+inline typename associated_allocator<T, Allocator>::type
+get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
+{
+ return associated_allocator<T, Allocator>::get(t, a);
+}
+
+#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Allocator = std::allocator<void> >
+using associated_allocator_t
+ = typename associated_allocator<T, Allocator>::type;
+
+#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
diff --git a/boost/asio/associated_executor.hpp b/boost/asio/associated_executor.hpp
new file mode 100644
index 0000000000..d0347afcfa
--- /dev/null
+++ b/boost/asio/associated_executor.hpp
@@ -0,0 +1,151 @@
+//
+// associated_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
+#define BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/is_executor.hpp>
+#include <boost/asio/system_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename>
+struct associated_executor_check
+{
+ typedef void type;
+};
+
+template <typename T, typename E, typename = void>
+struct associated_executor_impl
+{
+ typedef E type;
+
+ static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
+ {
+ return e;
+ }
+};
+
+template <typename T, typename E>
+struct associated_executor_impl<T, E,
+ typename associated_executor_check<typename T::executor_type>::type>
+{
+ typedef typename T::executor_type type;
+
+ static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
+ {
+ return t.get_executor();
+ }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the executor associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Executor shall be a type meeting the Executor requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c e is an object of type @c
+ * Executor.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Executor requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,e) and with return type @c type.
+ */
+template <typename T, typename Executor = system_executor>
+struct associated_executor
+{
+ /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
+ /// Otherwise @c Executor.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef see_below type;
+#else // defined(GENERATING_DOCUMENTATION)
+ typedef typename detail::associated_executor_impl<T, Executor>::type type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+ /// If @c T has a nested type @c executor_type, returns
+ /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
+ static type get(const T& t,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return detail::associated_executor_impl<T, Executor>::get(t, ex);
+ }
+};
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_executor<T>::type
+get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
+{
+ return associated_executor<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
+ */
+template <typename T, typename Executor>
+inline typename associated_executor<T, Executor>::type
+get_associated_executor(const T& t, const Executor& ex,
+ typename enable_if<is_executor<
+ Executor>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
+{
+ return associated_executor<T, Executor>::get(t, ex);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, typename
+ * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
+ */
+template <typename T, typename ExecutionContext>
+inline typename associated_executor<T,
+ typename ExecutionContext::executor_type>::type
+get_associated_executor(const T& t, ExecutionContext& ctx,
+ typename enable_if<is_convertible<ExecutionContext&,
+ execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
+{
+ return associated_executor<T,
+ typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
+}
+
+#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Executor = system_executor>
+using associated_executor_t = typename associated_executor<T, Executor>::type;
+
+#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
diff --git a/boost/asio/async_result.hpp b/boost/asio/async_result.hpp
index 6290b8462a..f49f2eb2e0 100644
--- a/boost/asio/async_result.hpp
+++ b/boost/asio/async_result.hpp
@@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/handler_type.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -25,10 +26,93 @@ namespace asio {
/// An interface for customising the behaviour of an initiating function.
/**
+ * The async_result traits class is used for determining:
+ *
+ * @li the concrete completion handler type to be called at the end of the
+ * asynchronous operation;
+ *
+ * @li the initiating function return type; and
+ *
+ * @li how the return value of the initiating function is obtained.
+ *
+ * The trait allows the handler and return types to be determined at the point
+ * where the specific completion handler signature is known.
+ *
+ * This template may be specialised for user-defined completion token types.
+ * The primary template assumes that the CompletionToken is the completion
+ * handler.
+ */
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+template <typename CompletionToken, typename Signature>
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+template <typename CompletionToken, typename Signature = void>
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+class async_result
+{
+public:
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ /// The concrete completion handler type for the specific signature.
+ typedef CompletionToken completion_handler_type;
+
+ /// The return type of the initiating function.
+ typedef void return_type;
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ // For backward compatibility, determine the concrete completion handler type
+ // by using the legacy handler_type trait.
+ typedef typename handler_type<CompletionToken, Signature>::type
+ completion_handler_type;
+
+ // For backward compatibility, determine the initiating function return type
+ // using the legacy single-parameter version of async_result.
+ typedef typename async_result<completion_handler_type>::type return_type;
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+
+ /// Construct an async result from a given handler.
+ /**
+ * When using a specalised async_result, the constructor has an opportunity
+ * to initialise some state associated with the completion handler, which is
+ * then returned from the initiating function.
+ */
+ explicit async_result(completion_handler_type& h)
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ // No data members to initialise.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ : legacy_result_(h)
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ {
+ (void)h;
+ }
+
+ /// Obtain the value to be returned from the initiating function.
+ return_type get()
+ {
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ // Nothing to do.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ return legacy_result_.get();
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ }
+
+private:
+ async_result(const async_result&) BOOST_ASIO_DELETED;
+ async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
+
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ // No data members.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ async_result<completion_handler_type> legacy_result_;
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// (Deprecated: Use two-parameter version of async_result.) An interface for
+/// customising the behaviour of an initiating function.
+/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
-class async_result
+class async_result<Handler>
{
public:
/// The return type of the initiating function.
@@ -50,29 +134,65 @@ public:
}
};
-namespace detail {
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-// Helper template to deduce the true type of a handler, capture a local copy
-// of the handler, and then create an async_result for the handler.
-template <typename Handler, typename Signature>
-struct async_result_init
+/// Helper template to deduce the handler type from a CompletionToken, capture
+/// a local copy of the handler, and then create an async_result for the
+/// handler.
+template <typename CompletionToken, typename Signature>
+struct async_completion
{
- explicit async_result_init(BOOST_ASIO_MOVE_ARG(Handler) orig_handler)
- : handler(BOOST_ASIO_MOVE_CAST(Handler)(orig_handler)),
- result(handler)
+ /// The real handler type to be used for the asynchronous operation.
+ typedef typename boost::asio::async_result<
+ typename decay<CompletionToken>::type,
+ Signature>::completion_handler_type completion_handler_type;
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Constructor.
+ /**
+ * The constructor creates the concrete completion handler and makes the link
+ * between the handler and the asynchronous result.
+ */
+ explicit async_completion(CompletionToken& token)
+ : completion_handler(static_cast<typename conditional<
+ is_same<CompletionToken, completion_handler_type>::value,
+ completion_handler_type&, CompletionToken&&>::type>(token)),
+ result(completion_handler)
+ {
+ }
+#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ explicit async_completion(typename decay<CompletionToken>::type& token)
+ : completion_handler(token),
+ result(completion_handler)
{
}
- typename handler_type<Handler, Signature>::type handler;
- async_result<typename handler_type<Handler, Signature>::type> result;
+ explicit async_completion(const typename decay<CompletionToken>::type& token)
+ : completion_handler(token),
+ result(completion_handler)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// A copy of, or reference to, a real handler object.
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ typename conditional<
+ is_same<CompletionToken, completion_handler_type>::value,
+ completion_handler_type&, completion_handler_type>::type completion_handler;
+#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ completion_handler_type completion_handler;
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// The result of the asynchronous operation's initiating function.
+ async_result<typename decay<CompletionToken>::type, Signature> result;
};
-template <typename Handler, typename Signature>
-struct async_result_type_helper
+namespace detail {
+
+template <typename CompletionToken, typename Signature>
+struct async_result_helper
+ : async_result<typename decay<CompletionToken>::type, Signature>
{
- typedef typename async_result<
- typename handler_type<Handler, Signature>::type
- >::type type;
};
} // namespace detail
@@ -82,15 +202,22 @@ struct async_result_type_helper
#include <boost/asio/detail/pop_options.hpp>
#if defined(GENERATING_DOCUMENTATION)
-# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
void_or_deduced
#elif defined(_MSC_VER) && (_MSC_VER < 1500)
-# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
- typename ::boost::asio::detail::async_result_type_helper<h, sig>::type
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
+ typename ::boost::asio::detail::async_result_helper< \
+ ct, sig>::return_type
+#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
+ typename ::boost::asio::detail::async_result_helper< \
+ ct, sig>::completion_handler_type
#else
-# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
+ typename ::boost::asio::async_result< \
+ typename ::boost::asio::decay<ct>::type, sig>::return_type
+#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
typename ::boost::asio::async_result< \
- typename ::boost::asio::handler_type<h, sig>::type>::type
+ typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif
#endif // BOOST_ASIO_ASYNC_RESULT_HPP
diff --git a/boost/asio/basic_datagram_socket.hpp b/boost/asio/basic_datagram_socket.hpp
index 22801ee081..c2aa00bf48 100644
--- a/boost/asio/basic_datagram_socket.hpp
+++ b/boost/asio/basic_datagram_socket.hpp
@@ -18,12 +18,15 @@
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/asio/basic_socket.hpp>
-#include <boost/asio/datagram_socket_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/datagram_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -38,18 +41,19 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol,
- typename DatagramSocketService = datagram_socket_service<Protocol> >
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
class basic_datagram_socket
- : public basic_socket<Protocol, DatagramSocketService>
+ : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// socket.
- typedef typename DatagramSocketService::native_handle_type native_type;
-
/// The native representation of a socket.
- typedef typename DatagramSocketService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket<
+ Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -62,12 +66,12 @@ public:
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
- * @param io_service The io_service object that the datagram socket will use
+ * @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*/
- explicit basic_datagram_socket(boost::asio::io_service& io_service)
- : basic_socket<Protocol, DatagramSocketService>(io_service)
+ explicit basic_datagram_socket(boost::asio::io_context& io_context)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
{
}
@@ -75,7 +79,7 @@ public:
/**
* This constructor creates and opens a datagram socket.
*
- * @param io_service The io_service object that the datagram socket will use
+ * @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -83,9 +87,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_service& io_service,
+ basic_datagram_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
{
}
@@ -96,7 +100,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_service The io_service object that the datagram socket will use
+ * @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -105,9 +109,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_service& io_service,
+ basic_datagram_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
- : basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
{
}
@@ -116,7 +120,7 @@ public:
* This constructor creates a datagram socket object to hold an existing
* native socket.
*
- * @param io_service The io_service object that the datagram socket will use
+ * @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -126,10 +130,10 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_service& io_service,
+ basic_datagram_socket(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol, DatagramSocketService>(
- io_service, protocol, native_socket)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+ io_context, protocol, native_socket)
{
}
@@ -142,11 +146,10 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_service&) constructor.
+ * constructed using the @c basic_datagram_socket(io_context&) constructor.
*/
basic_datagram_socket(basic_datagram_socket&& other)
- : basic_socket<Protocol, DatagramSocketService>(
- BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -159,12 +162,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_service&) constructor.
+ * constructed using the @c basic_datagram_socket(io_context&) constructor.
*/
basic_datagram_socket& operator=(basic_datagram_socket&& other)
{
- basic_socket<Protocol, DatagramSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
@@ -177,15 +179,13 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_service&) constructor.
+ * constructed using the @c basic_datagram_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename DatagramSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_datagram_socket(
- basic_datagram_socket<Protocol1, DatagramSocketService1>&& other,
+ basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol, DatagramSocketService>(
- BOOST_ASIO_MOVE_CAST2(basic_datagram_socket<
- Protocol1, DatagramSocketService1>)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -199,20 +199,27 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_service&) constructor.
+ * constructed using the @c basic_datagram_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename DatagramSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_datagram_socket>::type& operator=(
- basic_datagram_socket<Protocol1, DatagramSocketService1>&& other)
+ basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket<Protocol, DatagramSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST2(basic_datagram_socket<
- Protocol1, DatagramSocketService1>)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_datagram_socket()
+ {
+ }
+
/// Send some data on a connected socket.
/**
* This function is used to send data on the datagram socket. The function
@@ -318,7 +325,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@@ -343,8 +350,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous send on a connected socket.
@@ -369,7 +386,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@@ -386,8 +403,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Send a datagram to the specified endpoint.
@@ -501,7 +528,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -526,9 +553,20 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send_to(
+ this->get_implementation(), buffers, destination, 0,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous send.
@@ -556,7 +594,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -569,9 +607,20 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send_to(
+ this->get_implementation(), buffers, destination, flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive some data on a connected socket.
@@ -683,7 +732,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -709,8 +758,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive on a connected socket.
@@ -735,7 +794,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -752,8 +811,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive a datagram with the endpoint of the sender.
@@ -870,7 +939,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -892,9 +961,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_from(
+ this->get_implementation(), buffers, sender_endpoint, 0,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive.
@@ -924,7 +1004,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -937,9 +1017,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_from(
+ this->get_implementation(), buffers, sender_endpoint, flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
};
diff --git a/boost/asio/basic_deadline_timer.hpp b/boost/asio/basic_deadline_timer.hpp
index 930370046b..f7179a853e 100644
--- a/boost/asio/basic_deadline_timer.hpp
+++ b/boost/asio/basic_deadline_timer.hpp
@@ -22,10 +22,17 @@
#include <cstddef>
#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/time_traits.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/deadline_timer_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/deadline_timer_service.hpp>
+# define BOOST_ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
@@ -51,7 +58,7 @@ namespace asio {
* Performing a blocking wait:
* @code
* // Construct a timer without setting an expiry time.
- * boost::asio::deadline_timer timer(io_service);
+ * boost::asio::deadline_timer timer(io_context);
*
* // Set an expiry time relative to now.
* timer.expires_from_now(boost::posix_time::seconds(5));
@@ -74,7 +81,7 @@ namespace asio {
* ...
*
* // Construct a timer with an absolute expiry time.
- * boost::asio::deadline_timer timer(io_service,
+ * boost::asio::deadline_timer timer(io_context,
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
*
* // Start an asynchronous wait.
@@ -121,12 +128,15 @@ namespace asio {
* it contains the value boost::asio::error::operation_aborted.
*/
template <typename Time,
- typename TimeTraits = boost::asio::time_traits<Time>,
- typename TimerService = deadline_timer_service<Time, TimeTraits> >
+ typename TimeTraits = boost::asio::time_traits<Time>
+ BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)>
class basic_deadline_timer
- : public basic_io_object<TimerService>
+ : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
+ /// The type of the executor associated with the object.
+ typedef io_context::executor_type executor_type;
+
/// The time traits type.
typedef TimeTraits traits_type;
@@ -142,11 +152,11 @@ public:
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*/
- explicit basic_deadline_timer(boost::asio::io_service& io_service)
- : basic_io_object<TimerService>(io_service)
+ explicit basic_deadline_timer(boost::asio::io_context& io_context)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
}
@@ -154,18 +164,18 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
- basic_deadline_timer(boost::asio::io_service& io_service,
+ basic_deadline_timer(boost::asio::io_context& io_context,
const time_type& expiry_time)
- : basic_io_object<TimerService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
- this->service.expires_at(this->implementation, expiry_time, ec);
+ this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
@@ -173,21 +183,105 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
- basic_deadline_timer(boost::asio::io_service& io_service,
+ basic_deadline_timer(boost::asio::io_context& io_context,
const duration_type& expiry_time)
- : basic_io_object<TimerService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
- this->service.expires_from_now(this->implementation, expiry_time, ec);
+ this->get_service().expires_from_now(
+ this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
}
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_deadline_timer from another.
+ /**
+ * This constructor moves a timer from one object to another.
+ *
+ * @param other The other basic_deadline_timer object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_deadline_timer(io_context&) constructor.
+ */
+ basic_deadline_timer(basic_deadline_timer&& other)
+ : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_deadline_timer from another.
+ /**
+ * This assignment operator moves a timer from one object to another. Cancels
+ * any outstanding asynchronous operations associated with the target object.
+ *
+ * @param other The other basic_deadline_timer object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_deadline_timer(io_context&) constructor.
+ */
+ basic_deadline_timer& operator=(basic_deadline_timer&& other)
+ {
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destroys the timer.
+ /**
+ * This function destroys the timer, cancelling any outstanding asynchronous
+ * wait operations associated with the timer as if by calling @c cancel.
+ */
+ ~basic_deadline_timer()
+ {
+ }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_context()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_service()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
@@ -213,7 +307,7 @@ public:
std::size_t cancel()
{
boost::system::error_code ec;
- std::size_t s = this->service.cancel(this->implementation, ec);
+ std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
return s;
}
@@ -242,7 +336,7 @@ public:
*/
std::size_t cancel(boost::system::error_code& ec)
{
- return this->service.cancel(this->implementation, ec);
+ return this->get_service().cancel(this->get_implementation(), ec);
}
/// Cancels one asynchronous operation that is waiting on the timer.
@@ -272,7 +366,8 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
- std::size_t s = this->service.cancel_one(this->implementation, ec);
+ std::size_t s = this->get_service().cancel_one(
+ this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
@@ -303,7 +398,7 @@ public:
*/
std::size_t cancel_one(boost::system::error_code& ec)
{
- return this->service.cancel_one(this->implementation, ec);
+ return this->get_service().cancel_one(this->get_implementation(), ec);
}
/// Get the timer's expiry time as an absolute time.
@@ -313,7 +408,7 @@ public:
*/
time_type expires_at() const
{
- return this->service.expires_at(this->implementation);
+ return this->get_service().expires_at(this->get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -341,8 +436,8 @@ public:
std::size_t expires_at(const time_type& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->service.expires_at(
- this->implementation, expiry_time, ec);
+ std::size_t s = this->get_service().expires_at(
+ this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
@@ -372,7 +467,8 @@ public:
std::size_t expires_at(const time_type& expiry_time,
boost::system::error_code& ec)
{
- return this->service.expires_at(this->implementation, expiry_time, ec);
+ return this->get_service().expires_at(
+ this->get_implementation(), expiry_time, ec);
}
/// Get the timer's expiry time relative to now.
@@ -382,7 +478,7 @@ public:
*/
duration_type expires_from_now() const
{
- return this->service.expires_from_now(this->implementation);
+ return this->get_service().expires_from_now(this->get_implementation());
}
/// Set the timer's expiry time relative to now.
@@ -410,8 +506,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->service.expires_from_now(
- this->implementation, expiry_time, ec);
+ std::size_t s = this->get_service().expires_from_now(
+ this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@@ -441,8 +537,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time,
boost::system::error_code& ec)
{
- return this->service.expires_from_now(
- this->implementation, expiry_time, ec);
+ return this->get_service().expires_from_now(
+ this->get_implementation(), expiry_time, ec);
}
/// Perform a blocking wait on the timer.
@@ -455,7 +551,7 @@ public:
void wait()
{
boost::system::error_code ec;
- this->service.wait(this->implementation, ec);
+ this->get_service().wait(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -468,7 +564,7 @@ public:
*/
void wait(boost::system::error_code& ec)
{
- this->service.wait(this->implementation, ec);
+ this->get_service().wait(this->get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -493,7 +589,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
@@ -504,8 +600,18 @@ public:
// not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
- return this->service.async_wait(this->implementation,
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_wait(this->get_implementation(),
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
};
@@ -514,6 +620,10 @@ public:
#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/basic_io_object.hpp b/boost/asio/basic_io_object.hpp
index d490a161f6..87653b5c53 100644
--- a/boost/asio/basic_io_object.hpp
+++ b/boost/asio/basic_io_object.hpp
@@ -16,7 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -68,17 +68,43 @@ public:
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type;
- /// Get the io_service associated with the object.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
/**
- * This function may be used to obtain the io_service object that the I/O
+ * This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
- * @return A reference to the io_service object that the I/O object will use
+ * @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
- boost::asio::io_service& get_io_service()
+ boost::asio::io_context& get_io_context()
{
- return service.get_io_service();
+ return service_.get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_service()
+ {
+ return service_.get_io_context();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// The type of the executor associated with the object.
+ typedef boost::asio::io_context::executor_type executor_type;
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return service_.get_io_context().get_executor();
}
protected:
@@ -87,10 +113,10 @@ protected:
* Performs:
* @code get_service().construct(get_implementation()); @endcode
*/
- explicit basic_io_object(boost::asio::io_service& io_service)
- : service(boost::asio::use_service<IoObjectService>(io_service))
+ explicit basic_io_object(boost::asio::io_context& io_context)
+ : service_(boost::asio::use_service<IoObjectService>(io_context))
{
- service.construct(implementation);
+ service_.construct(implementation_);
}
#if defined(GENERATING_DOCUMENTATION)
@@ -127,47 +153,42 @@ protected:
*/
~basic_io_object()
{
- service.destroy(implementation);
+ service_.destroy(implementation_);
}
/// Get the service associated with the I/O object.
service_type& get_service()
{
- return service;
+ return service_;
}
/// Get the service associated with the I/O object.
const service_type& get_service() const
{
- return service;
+ return service_;
}
- /// (Deprecated: Use get_service().) The service associated with the I/O
- /// object.
- /**
- * @note Available only for services that do not support movability.
- */
- service_type& service;
-
/// Get the underlying implementation of the I/O object.
implementation_type& get_implementation()
{
- return implementation;
+ return implementation_;
}
/// Get the underlying implementation of the I/O object.
const implementation_type& get_implementation() const
{
- return implementation;
+ return implementation_;
}
- /// (Deprecated: Use get_implementation().) The underlying implementation of
- /// the I/O object.
- implementation_type implementation;
-
private:
basic_io_object(const basic_io_object&);
basic_io_object& operator=(const basic_io_object&);
+
+ // The service associated with the I/O object.
+ service_type& service_;
+
+ /// The underlying implementation of the I/O object.
+ implementation_type implementation_;
};
#if defined(BOOST_ASIO_HAS_MOVE)
@@ -179,43 +200,57 @@ public:
typedef IoObjectService service_type;
typedef typename service_type::implementation_type implementation_type;
- boost::asio::io_service& get_io_service()
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ boost::asio::io_context& get_io_context()
+ {
+ return service_->get_io_context();
+ }
+
+ boost::asio::io_context& get_io_service()
{
- return service_->get_io_service();
+ return service_->get_io_context();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ typedef boost::asio::io_context::executor_type executor_type;
+
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return service_->get_io_context().get_executor();
}
protected:
- explicit basic_io_object(boost::asio::io_service& io_service)
- : service_(&boost::asio::use_service<IoObjectService>(io_service))
+ explicit basic_io_object(boost::asio::io_context& io_context)
+ : service_(&boost::asio::use_service<IoObjectService>(io_context))
{
- service_->construct(implementation);
+ service_->construct(implementation_);
}
basic_io_object(basic_io_object&& other)
: service_(&other.get_service())
{
- service_->move_construct(implementation, other.implementation);
+ service_->move_construct(implementation_, other.implementation_);
}
template <typename IoObjectService1>
basic_io_object(IoObjectService1& other_service,
typename IoObjectService1::implementation_type& other_implementation)
: service_(&boost::asio::use_service<IoObjectService>(
- other_service.get_io_service()))
+ other_service.get_io_context()))
{
- service_->converting_move_construct(implementation,
+ service_->converting_move_construct(implementation_,
other_service, other_implementation);
}
~basic_io_object()
{
- service_->destroy(implementation);
+ service_->destroy(implementation_);
}
basic_io_object& operator=(basic_io_object&& other)
{
- service_->move_assign(implementation,
- *other.service_, other.implementation);
+ service_->move_assign(implementation_,
+ *other.service_, other.implementation_);
service_ = other.service_;
return *this;
}
@@ -232,21 +267,20 @@ protected:
implementation_type& get_implementation()
{
- return implementation;
+ return implementation_;
}
const implementation_type& get_implementation() const
{
- return implementation;
+ return implementation_;
}
- implementation_type implementation;
-
private:
basic_io_object(const basic_io_object&);
void operator=(const basic_io_object&);
IoObjectService* service_;
+ implementation_type implementation_;
};
#endif // defined(BOOST_ASIO_HAS_MOVE)
diff --git a/boost/asio/basic_raw_socket.hpp b/boost/asio/basic_raw_socket.hpp
index 85f8f42642..09058de224 100644
--- a/boost/asio/basic_raw_socket.hpp
+++ b/boost/asio/basic_raw_socket.hpp
@@ -22,7 +22,10 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/raw_socket_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/raw_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
@@ -38,18 +41,19 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol,
- typename RawSocketService = raw_socket_service<Protocol> >
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
class basic_raw_socket
- : public basic_socket<Protocol, RawSocketService>
+ : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// socket.
- typedef typename RawSocketService::native_handle_type native_type;
-
/// The native representation of a socket.
- typedef typename RawSocketService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket<
+ Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -62,12 +66,12 @@ public:
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
- * @param io_service The io_service object that the raw socket will use
+ * @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*/
- explicit basic_raw_socket(boost::asio::io_service& io_service)
- : basic_socket<Protocol, RawSocketService>(io_service)
+ explicit basic_raw_socket(boost::asio::io_context& io_context)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
{
}
@@ -75,7 +79,7 @@ public:
/**
* This constructor creates and opens a raw socket.
*
- * @param io_service The io_service object that the raw socket will use
+ * @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -83,9 +87,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_service& io_service,
+ basic_raw_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_socket<Protocol, RawSocketService>(io_service, protocol)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
{
}
@@ -96,7 +100,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_service The io_service object that the raw socket will use
+ * @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -105,9 +109,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_service& io_service,
+ basic_raw_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
- : basic_socket<Protocol, RawSocketService>(io_service, endpoint)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
{
}
@@ -116,7 +120,7 @@ public:
* This constructor creates a raw socket object to hold an existing
* native socket.
*
- * @param io_service The io_service object that the raw socket will use
+ * @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
*
@@ -126,10 +130,10 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_service& io_service,
+ basic_raw_socket(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol, RawSocketService>(
- io_service, protocol, native_socket)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+ io_context, protocol, native_socket)
{
}
@@ -142,11 +146,10 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_service&) constructor.
+ * constructed using the @c basic_raw_socket(io_context&) constructor.
*/
basic_raw_socket(basic_raw_socket&& other)
- : basic_socket<Protocol, RawSocketService>(
- BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -158,12 +161,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_service&) constructor.
+ * constructed using the @c basic_raw_socket(io_context&) constructor.
*/
basic_raw_socket& operator=(basic_raw_socket&& other)
{
- basic_socket<Protocol, RawSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
@@ -175,14 +177,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_service&) constructor.
+ * constructed using the @c basic_raw_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename RawSocketService1>
- basic_raw_socket(basic_raw_socket<Protocol1, RawSocketService1>&& other,
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+ basic_raw_socket(basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol, RawSocketService>(
- BOOST_ASIO_MOVE_CAST2(basic_raw_socket<
- Protocol1, RawSocketService1>)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -194,20 +194,27 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_service&) constructor.
+ * constructed using the @c basic_raw_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename RawSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_raw_socket>::type& operator=(
- basic_raw_socket<Protocol1, RawSocketService1>&& other)
+ basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket<Protocol, RawSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST2(basic_raw_socket<
- Protocol1, RawSocketService1>)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_raw_socket()
+ {
+ }
+
/// Send some data on a connected socket.
/**
* This function is used to send data on the raw socket. The function call
@@ -310,7 +317,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@@ -335,8 +342,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous send on a connected socket.
@@ -361,7 +378,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@@ -378,8 +395,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Send raw data to the specified endpoint.
@@ -493,7 +520,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -518,8 +545,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send_to(this->get_implementation(),
+ buffers, destination, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous send.
@@ -547,7 +584,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -560,9 +597,20 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send_to(
+ this->get_implementation(), buffers, destination, flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive some data on a connected socket.
@@ -674,7 +722,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -700,8 +748,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive on a connected socket.
@@ -726,7 +784,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -743,8 +801,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive raw data with the endpoint of the sender.
@@ -861,7 +929,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -883,9 +951,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_from(
+ this->get_implementation(), buffers, sender_endpoint, 0,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive.
@@ -915,7 +994,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -928,9 +1007,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_from(
+ this->get_implementation(), buffers, sender_endpoint, flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
};
diff --git a/boost/asio/basic_seq_packet_socket.hpp b/boost/asio/basic_seq_packet_socket.hpp
index c8e43f77d6..a48a5b847e 100644
--- a/boost/asio/basic_seq_packet_socket.hpp
+++ b/boost/asio/basic_seq_packet_socket.hpp
@@ -21,7 +21,10 @@
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/seq_packet_socket_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/seq_packet_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
@@ -37,19 +40,19 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol,
- typename SeqPacketSocketService = seq_packet_socket_service<Protocol> >
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
class basic_seq_packet_socket
- : public basic_socket<Protocol, SeqPacketSocketService>
+ : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// socket.
- typedef typename SeqPacketSocketService::native_handle_type native_type;
-
/// The native representation of a socket.
- typedef typename SeqPacketSocketService::native_handle_type
- native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket<
+ Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -63,12 +66,12 @@ public:
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
- * @param io_service The io_service object that the sequenced packet socket
+ * @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
*/
- explicit basic_seq_packet_socket(boost::asio::io_service& io_service)
- : basic_socket<Protocol, SeqPacketSocketService>(io_service)
+ explicit basic_seq_packet_socket(boost::asio::io_context& io_context)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
{
}
@@ -78,7 +81,7 @@ public:
* needs to be connected or accepted before data can be sent or received on
* it.
*
- * @param io_service The io_service object that the sequenced packet socket
+ * @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
*
@@ -86,9 +89,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_service& io_service,
+ basic_seq_packet_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_socket<Protocol, SeqPacketSocketService>(io_service, protocol)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
{
}
@@ -99,7 +102,7 @@ public:
* it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint.
*
- * @param io_service The io_service object that the sequenced packet socket
+ * @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
*
@@ -108,9 +111,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_service& io_service,
+ basic_seq_packet_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
- : basic_socket<Protocol, SeqPacketSocketService>(io_service, endpoint)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
{
}
@@ -119,7 +122,7 @@ public:
* This constructor creates a sequenced packet socket object to hold an
* existing native socket.
*
- * @param io_service The io_service object that the sequenced packet socket
+ * @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
*
@@ -129,10 +132,10 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_service& io_service,
+ basic_seq_packet_socket(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol, SeqPacketSocketService>(
- io_service, protocol, native_socket)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+ io_context, protocol, native_socket)
{
}
@@ -146,11 +149,10 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+ * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
*/
basic_seq_packet_socket(basic_seq_packet_socket&& other)
- : basic_socket<Protocol, SeqPacketSocketService>(
- BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -163,12 +165,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+ * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
*/
basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
{
- basic_socket<Protocol, SeqPacketSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
@@ -182,15 +183,13 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+ * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SeqPacketSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_seq_packet_socket(
- basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other,
+ basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol, SeqPacketSocketService>(
- BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket<
- Protocol1, SeqPacketSocketService1>)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -204,20 +203,27 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+ * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SeqPacketSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_seq_packet_socket>::type& operator=(
- basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other)
+ basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket<Protocol, SeqPacketSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket<
- Protocol1, SeqPacketSocketService1>)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_seq_packet_socket()
+ {
+ }
+
/// Send some data on the socket.
/**
* This function is used to send data on the sequenced packet socket. The
@@ -300,7 +306,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -322,8 +328,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive some data on the socket.
@@ -360,8 +376,13 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ std::size_t s = this->get_service().receive_with_flags(
+ this->get_implementation(), buffers, 0, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -407,8 +428,13 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, in_flags, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ std::size_t s = this->get_service().receive_with_flags(
+ this->get_implementation(), buffers, in_flags, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -441,8 +467,13 @@ public:
socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, boost::system::error_code& ec)
{
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive(this->get_implementation(),
buffers, in_flags, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().receive_with_flags(this->get_implementation(),
+ buffers, in_flags, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive.
@@ -471,7 +502,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -494,9 +525,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, 0, out_flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_with_flags(
+ this->get_implementation(), buffers, 0, out_flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive.
@@ -527,7 +569,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -553,9 +595,20 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, in_flags, out_flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive_with_flags(
+ this->get_implementation(), buffers, in_flags, out_flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
};
diff --git a/boost/asio/basic_serial_port.hpp b/boost/asio/basic_serial_port.hpp
index bfc78afaf6..af2193f7cb 100644
--- a/boost/asio/basic_serial_port.hpp
+++ b/boost/asio/basic_serial_port.hpp
@@ -18,6 +18,8 @@
#include <boost/asio/detail/config.hpp>
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION)
@@ -49,10 +51,6 @@ class basic_serial_port
public serial_port_base
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// serial port.
- typedef typename SerialPortService::native_handle_type native_type;
-
/// The native representation of a serial port.
typedef typename SerialPortService::native_handle_type native_handle_type;
@@ -63,11 +61,11 @@ public:
/**
* This constructor creates a serial port without opening it.
*
- * @param io_service The io_service object that the serial port will use to
+ * @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
*/
- explicit basic_serial_port(boost::asio::io_service& io_service)
- : basic_io_object<SerialPortService>(io_service)
+ explicit basic_serial_port(boost::asio::io_context& io_context)
+ : basic_io_object<SerialPortService>(io_context)
{
}
@@ -76,15 +74,15 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
- * @param io_service The io_service object that the serial port will use to
+ * @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
*
* @param device The platform-specific device name for this serial
* port.
*/
- explicit basic_serial_port(boost::asio::io_service& io_service,
+ explicit basic_serial_port(boost::asio::io_context& io_context,
const char* device)
- : basic_io_object<SerialPortService>(io_service)
+ : basic_io_object<SerialPortService>(io_context)
{
boost::system::error_code ec;
this->get_service().open(this->get_implementation(), device, ec);
@@ -96,15 +94,15 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
- * @param io_service The io_service object that the serial port will use to
+ * @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
*
* @param device The platform-specific device name for this serial
* port.
*/
- explicit basic_serial_port(boost::asio::io_service& io_service,
+ explicit basic_serial_port(boost::asio::io_context& io_context,
const std::string& device)
- : basic_io_object<SerialPortService>(io_service)
+ : basic_io_object<SerialPortService>(io_context)
{
boost::system::error_code ec;
this->get_service().open(this->get_implementation(), device, ec);
@@ -116,16 +114,16 @@ public:
* This constructor creates a serial port object to hold an existing native
* serial port.
*
- * @param io_service The io_service object that the serial port will use to
+ * @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
*
* @param native_serial_port A native serial port.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_serial_port(boost::asio::io_service& io_service,
+ basic_serial_port(boost::asio::io_context& io_context,
const native_handle_type& native_serial_port)
- : basic_io_object<SerialPortService>(io_service)
+ : basic_io_object<SerialPortService>(io_context)
{
boost::system::error_code ec;
this->get_service().assign(this->get_implementation(),
@@ -142,7 +140,7 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_serial_port(io_service&) constructor.
+ * constructed using the @c basic_serial_port(io_context&) constructor.
*/
basic_serial_port(basic_serial_port&& other)
: basic_io_object<SerialPortService>(
@@ -158,7 +156,7 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_serial_port(io_service&) constructor.
+ * constructed using the @c basic_serial_port(io_context&) constructor.
*/
basic_serial_port& operator=(basic_serial_port&& other)
{
@@ -220,10 +218,11 @@ public:
*
* @param ec Set the indicate what error occurred, if any.
*/
- boost::system::error_code open(const std::string& device,
+ BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
boost::system::error_code& ec)
{
- return this->get_service().open(this->get_implementation(), device, ec);
+ this->get_service().open(this->get_implementation(), device, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native serial port to the serial port.
@@ -250,11 +249,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code assign(const native_handle_type& native_serial_port,
+ BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
boost::system::error_code& ec)
{
- return this->get_service().assign(this->get_implementation(),
+ this->get_service().assign(this->get_implementation(),
native_serial_port, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the serial port is open.
@@ -286,21 +286,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return this->get_service().close(this->get_implementation(), ec);
- }
-
- /// (Deprecated: Use native_handle().) Get the native serial port
- /// representation.
- /**
- * 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.
- */
- native_type native()
- {
- return this->get_service().native_handle(this->get_implementation());
+ this->get_service().close(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the native serial port representation.
@@ -337,9 +326,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code cancel(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- return this->get_service().cancel(this->get_implementation(), ec);
+ this->get_service().cancel(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Send a break sequence to the serial port.
@@ -363,9 +353,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code send_break(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
{
- return this->get_service().send_break(this->get_implementation(), ec);
+ this->get_service().send_break(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Set an option on the serial port.
@@ -407,11 +398,11 @@ public:
* boost::asio::serial_port_base::character_size
*/
template <typename SettableSerialPortOption>
- boost::system::error_code set_option(const SettableSerialPortOption& option,
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
boost::system::error_code& ec)
{
- return this->get_service().set_option(
- this->get_implementation(), option, ec);
+ this->get_service().set_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the serial port.
@@ -455,11 +446,11 @@ public:
* boost::asio::serial_port_base::character_size
*/
template <typename GettableSerialPortOption>
- boost::system::error_code get_option(GettableSerialPortOption& option,
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
boost::system::error_code& ec)
{
- return this->get_service().get_option(
- this->get_implementation(), option, ec);
+ this->get_service().get_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Write some data to the serial port.
@@ -543,7 +534,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -655,7 +646,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -694,4 +685,6 @@ public:
#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP
diff --git a/boost/asio/basic_signal_set.hpp b/boost/asio/basic_signal_set.hpp
index 608bc0a6d8..3c00fa6e26 100644
--- a/boost/asio/basic_signal_set.hpp
+++ b/boost/asio/basic_signal_set.hpp
@@ -17,6 +17,8 @@
#include <boost/asio/detail/config.hpp>
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <boost/asio/basic_io_object.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/throw_error.hpp>
@@ -55,7 +57,7 @@ namespace asio {
* ...
*
* // Construct a signal set registered for process termination.
- * boost::asio::signal_set signals(io_service, SIGINT, SIGTERM);
+ * boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
*
* // Start an asynchronous wait for one of the signals to occur.
* signals.async_wait(handler);
@@ -99,11 +101,11 @@ public:
/**
* This constructor creates a signal set without registering for any signals.
*
- * @param io_service The io_service object that the signal set will use to
+ * @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
*/
- explicit basic_signal_set(boost::asio::io_service& io_service)
- : basic_io_object<SignalSetService>(io_service)
+ explicit basic_signal_set(boost::asio::io_context& io_context)
+ : basic_io_object<SignalSetService>(io_context)
{
}
@@ -111,20 +113,20 @@ public:
/**
* This constructor creates a signal set and registers for one signal.
*
- * @param io_service The io_service object that the signal set will use to
+ * @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
*
* @param signal_number_1 The signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_service);
+ * @code boost::asio::signal_set signals(io_context);
* signals.add(signal_number_1); @endcode
*/
- basic_signal_set(boost::asio::io_service& io_service, int signal_number_1)
- : basic_io_object<SignalSetService>(io_service)
+ basic_signal_set(boost::asio::io_context& io_context, int signal_number_1)
+ : basic_io_object<SignalSetService>(io_context)
{
boost::system::error_code ec;
- this->service.add(this->implementation, signal_number_1, ec);
+ this->get_service().add(this->get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -132,7 +134,7 @@ public:
/**
* This constructor creates a signal set and registers for two signals.
*
- * @param io_service The io_service object that the signal set will use to
+ * @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
*
* @param signal_number_1 The first signal number to be added.
@@ -140,18 +142,18 @@ public:
* @param signal_number_2 The second signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_service);
+ * @code boost::asio::signal_set signals(io_context);
* signals.add(signal_number_1);
* signals.add(signal_number_2); @endcode
*/
- basic_signal_set(boost::asio::io_service& io_service, int signal_number_1,
+ basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
int signal_number_2)
- : basic_io_object<SignalSetService>(io_service)
+ : basic_io_object<SignalSetService>(io_context)
{
boost::system::error_code ec;
- this->service.add(this->implementation, signal_number_1, ec);
+ this->get_service().add(this->get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
- this->service.add(this->implementation, signal_number_2, ec);
+ this->get_service().add(this->get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -159,7 +161,7 @@ public:
/**
* This constructor creates a signal set and registers for three signals.
*
- * @param io_service The io_service object that the signal set will use to
+ * @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
*
* @param signal_number_1 The first signal number to be added.
@@ -169,21 +171,21 @@ public:
* @param signal_number_3 The third signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_service);
+ * @code boost::asio::signal_set signals(io_context);
* signals.add(signal_number_1);
* signals.add(signal_number_2);
* signals.add(signal_number_3); @endcode
*/
- basic_signal_set(boost::asio::io_service& io_service, int signal_number_1,
+ basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
int signal_number_2, int signal_number_3)
- : basic_io_object<SignalSetService>(io_service)
+ : basic_io_object<SignalSetService>(io_context)
{
boost::system::error_code ec;
- this->service.add(this->implementation, signal_number_1, ec);
+ this->get_service().add(this->get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
- this->service.add(this->implementation, signal_number_2, ec);
+ this->get_service().add(this->get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
- this->service.add(this->implementation, signal_number_3, ec);
+ this->get_service().add(this->get_implementation(), signal_number_3, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -199,7 +201,7 @@ public:
void add(int signal_number)
{
boost::system::error_code ec;
- this->service.add(this->implementation, signal_number, ec);
+ this->get_service().add(this->get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -212,10 +214,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code add(int signal_number,
- boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID add(int signal_number, boost::system::error_code& ec)
{
- return this->service.add(this->implementation, signal_number, ec);
+ this->get_service().add(this->get_implementation(), signal_number, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Remove a signal from a signal_set.
@@ -233,7 +235,7 @@ public:
void remove(int signal_number)
{
boost::system::error_code ec;
- this->service.remove(this->implementation, signal_number, ec);
+ this->get_service().remove(this->get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "remove");
}
@@ -249,10 +251,11 @@ public:
* @note Removes any notifications that have been queued for the specified
* signal number.
*/
- boost::system::error_code remove(int signal_number,
+ BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
boost::system::error_code& ec)
{
- return this->service.remove(this->implementation, signal_number, ec);
+ this->get_service().remove(this->get_implementation(), signal_number, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Remove all signals from a signal_set.
@@ -267,7 +270,7 @@ public:
void clear()
{
boost::system::error_code ec;
- this->service.clear(this->implementation, ec);
+ this->get_service().clear(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "clear");
}
@@ -280,9 +283,10 @@ public:
*
* @note Removes all queued notifications.
*/
- boost::system::error_code clear(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
{
- return this->service.clear(this->implementation, ec);
+ this->get_service().clear(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Cancel all operations associated with the signal set.
@@ -309,7 +313,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->service.cancel(this->implementation, ec);
+ this->get_service().cancel(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -334,9 +338,10 @@ public:
* These handlers can no longer be cancelled, and therefore are passed an
* error code that indicates the successful completion of the wait operation.
*/
- boost::system::error_code cancel(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- return this->service.cancel(this->implementation, ec);
+ this->get_service().cancel(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous operation to wait for a signal to be delivered.
@@ -362,7 +367,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename SignalHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
@@ -373,7 +378,7 @@ public:
// not meet the documented type requirements for a SignalHandler.
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
- return this->service.async_wait(this->implementation,
+ return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
}
};
@@ -383,4 +388,6 @@ public:
#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP
diff --git a/boost/asio/basic_socket.hpp b/boost/asio/basic_socket.hpp
index 777f6a9ce1..cf51470690 100644
--- a/boost/asio/basic_socket.hpp
+++ b/boost/asio/basic_socket.hpp
@@ -22,8 +22,26 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/post.hpp>
#include <boost/asio/socket_base.hpp>
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/winrt_ssocket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
+# elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
+# else
+# include <boost/asio/detail/reactive_socket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
+# endif
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -38,18 +56,21 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol, typename SocketService>
+template <typename Protocol BOOST_ASIO_SVC_TPARAM>
class basic_socket
- : public basic_io_object<SocketService>,
+ : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
public socket_base
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// socket.
- typedef typename SocketService::native_handle_type native_type;
+ /// The type of the executor associated with the object.
+ typedef io_context::executor_type executor_type;
/// The native representation of a socket.
- typedef typename SocketService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -57,18 +78,20 @@ public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
/// A basic_socket is always the lowest layer.
- typedef basic_socket<Protocol, SocketService> lowest_layer_type;
+ typedef basic_socket<Protocol BOOST_ASIO_SVC_TARG> lowest_layer_type;
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Construct a basic_socket without opening it.
/**
* This constructor creates a socket without opening it.
*
- * @param io_service The io_service object that the socket will use to
+ * @param io_context The io_context object that the socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
- explicit basic_socket(boost::asio::io_service& io_service)
- : basic_io_object<SocketService>(io_service)
+ explicit basic_socket(boost::asio::io_context& io_context)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
}
@@ -76,16 +99,16 @@ public:
/**
* This constructor creates and opens a socket.
*
- * @param io_service The io_service object that the socket will use to
+ * @param io_context The io_context object that the socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_service& io_service,
+ basic_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_io_object<SocketService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
this->get_service().open(this->get_implementation(), protocol, ec);
@@ -99,7 +122,7 @@ public:
* specified endpoint on the local machine. The protocol used is the protocol
* associated with the given endpoint.
*
- * @param io_service The io_service object that the socket will use to
+ * @param io_context The io_context object that the socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the socket will
@@ -107,9 +130,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_service& io_service,
+ basic_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
- : basic_io_object<SocketService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
const protocol_type protocol = endpoint.protocol();
@@ -123,7 +146,7 @@ public:
/**
* This constructor creates a socket object to hold an existing native socket.
*
- * @param io_service The io_service object that the socket will use to
+ * @param io_context The io_context object that the socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
@@ -132,9 +155,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_service& io_service,
+ basic_socket(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_io_object<SocketService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
this->get_service().assign(this->get_implementation(),
@@ -151,11 +174,10 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
basic_socket(basic_socket&& other)
- : basic_io_object<SocketService>(
- BOOST_ASIO_MOVE_CAST(basic_socket)(other))
+ : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
{
}
@@ -167,17 +189,16 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
basic_socket& operator=(basic_socket&& other)
{
- basic_io_object<SocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_socket)(other));
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
return *this;
}
// All sockets have access to each other's implementations.
- template <typename Protocol1, typename SocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
friend class basic_socket;
/// Move-construct a basic_socket from a socket of another protocol type.
@@ -188,12 +209,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SocketService1>
- basic_socket(basic_socket<Protocol1, SocketService1>&& other,
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+ basic_socket(basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<SocketService>(
+ : basic_io_object<BOOST_ASIO_SVC_T>(
other.get_service(), other.get_implementation())
{
}
@@ -206,21 +227,60 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_socket>::type& operator=(
- basic_socket<Protocol1, SocketService1>&& other)
+ basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket tmp(BOOST_ASIO_MOVE_CAST2(basic_socket<
- Protocol1, SocketService1>)(other));
- basic_io_object<SocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_socket)(tmp));
+ basic_socket tmp(std::move(other));
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_context()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_service()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
@@ -248,6 +308,7 @@ public:
{
return *this;
}
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Open the socket using the specified protocol.
/**
@@ -259,7 +320,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* socket.open(boost::asio::ip::tcp::v4());
* @endcode
*/
@@ -280,7 +341,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::system::error_code ec;
* socket.open(boost::asio::ip::tcp::v4(), ec);
* if (ec)
@@ -289,10 +350,11 @@ public:
* }
* @endcode
*/
- boost::system::error_code open(const protocol_type& protocol,
+ BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
boost::system::error_code& ec)
{
- return this->get_service().open(this->get_implementation(), protocol, ec);
+ this->get_service().open(this->get_implementation(), protocol, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to the socket.
@@ -324,11 +386,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code assign(const protocol_type& protocol,
+ BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_socket, boost::system::error_code& ec)
{
- return this->get_service().assign(this->get_implementation(),
+ this->get_service().assign(this->get_implementation(),
protocol, native_socket, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
@@ -367,7 +430,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::system::error_code ec;
* socket.close(ec);
@@ -380,20 +443,62 @@ public:
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
*/
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return this->get_service().close(this->get_implementation(), ec);
+ this->get_service().close(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
- /// (Deprecated: Use native_handle().) Get the native socket representation.
+ /// Release ownership of the underlying native socket.
/**
- * 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.
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release()
+ {
+ boost::system::error_code ec;
+ native_handle_type s = this->get_service().release(
+ this->get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "release");
+ return s;
+ }
+
+ /// Release ownership of the underlying native socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
*/
- native_type native()
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release(boost::system::error_code& ec)
{
- return this->get_service().native_handle(this->get_implementation());
+ return this->get_service().release(this->get_implementation(), ec);
}
/// Get the native socket representation.
@@ -496,9 +601,10 @@ public:
"operation_not_supported when used on Windows XP, Windows Server 2003, "
"or earlier. Consult documentation for details."))
#endif
- boost::system::error_code cancel(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- return this->get_service().cancel(this->get_implementation(), ec);
+ this->get_service().cancel(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
@@ -580,7 +686,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* socket.open(boost::asio::ip::tcp::v4());
* socket.bind(boost::asio::ip::tcp::endpoint(
* boost::asio::ip::tcp::v4(), 12345));
@@ -605,7 +711,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* socket.open(boost::asio::ip::tcp::v4());
* boost::system::error_code ec;
* socket.bind(boost::asio::ip::tcp::endpoint(
@@ -616,10 +722,11 @@ public:
* }
* @endcode
*/
- boost::system::error_code bind(const endpoint_type& endpoint,
+ BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
boost::system::error_code& ec)
{
- return this->get_service().bind(this->get_implementation(), endpoint, ec);
+ this->get_service().bind(this->get_implementation(), endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the socket to the specified endpoint.
@@ -639,7 +746,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* socket.connect(endpoint);
@@ -675,7 +782,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* boost::system::error_code ec;
@@ -686,20 +793,21 @@ public:
* }
* @endcode
*/
- boost::system::error_code connect(const endpoint_type& peer_endpoint,
+ BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
boost::system::error_code& ec)
{
if (!is_open())
{
- if (this->get_service().open(this->get_implementation(),
- peer_endpoint.protocol(), ec))
+ this->get_service().open(this->get_implementation(),
+ peer_endpoint.protocol(), ec);
+ if (ec)
{
- return ec;
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
}
- return this->get_service().connect(
- this->get_implementation(), peer_endpoint, ec);
+ this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
@@ -723,7 +831,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* @code
@@ -737,7 +845,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* socket.async_connect(endpoint, connect_handler);
@@ -757,24 +865,34 @@ public:
{
boost::system::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
- if (this->get_service().open(this->get_implementation(), protocol, ec))
+ this->get_service().open(this->get_implementation(), protocol, ec);
+ if (ec)
{
- detail::async_result_init<
- ConnectHandler, void (boost::system::error_code)> init(
- BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
+ async_completion<ConnectHandler,
+ void (boost::system::error_code)> init(handler);
- this->get_io_service().post(
+ boost::asio::post(this->get_executor(),
boost::asio::detail::bind_handler(
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(
ConnectHandler, void (boost::system::error_code)))(
- init.handler), ec));
+ init.completion_handler), ec));
return init.result.get();
}
}
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_connect(this->get_implementation(),
peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ConnectHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_connect(
+ this->get_implementation(), peer_endpoint, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Set an option on the socket.
@@ -805,7 +923,7 @@ public:
* @par Example
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::no_delay option(true);
* socket.set_option(option);
@@ -847,7 +965,7 @@ public:
* @par Example
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::no_delay option(true);
* boost::system::error_code ec;
@@ -859,11 +977,11 @@ public:
* @endcode
*/
template <typename SettableSocketOption>
- boost::system::error_code set_option(const SettableSocketOption& option,
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
boost::system::error_code& ec)
{
- return this->get_service().set_option(
- this->get_implementation(), option, ec);
+ this->get_service().set_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the socket.
@@ -894,7 +1012,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::socket::keep_alive option;
* socket.get_option(option);
@@ -937,7 +1055,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::socket::keep_alive option;
* boost::system::error_code ec;
@@ -950,11 +1068,11 @@ public:
* @endcode
*/
template <typename GettableSocketOption>
- boost::system::error_code get_option(GettableSocketOption& option,
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
boost::system::error_code& ec) const
{
- return this->get_service().get_option(
- this->get_implementation(), option, ec);
+ this->get_service().get_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
@@ -972,7 +1090,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::socket::bytes_readable command;
* socket.io_control(command);
@@ -1002,7 +1120,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::socket::bytes_readable command;
* boost::system::error_code ec;
@@ -1015,11 +1133,11 @@ public:
* @endcode
*/
template <typename IoControlCommand>
- boost::system::error_code io_control(IoControlCommand& command,
+ BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
boost::system::error_code& ec)
{
- return this->get_service().io_control(
- this->get_implementation(), command, ec);
+ this->get_service().io_control(this->get_implementation(), command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
@@ -1071,11 +1189,11 @@ public:
* operations. Asynchronous operations will never fail with the error
* boost::asio::error::would_block.
*/
- boost::system::error_code non_blocking(
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(
bool mode, boost::system::error_code& ec)
{
- return this->get_service().non_blocking(
- this->get_implementation(), mode, ec);
+ this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
@@ -1135,7 +1253,7 @@ public:
* || ec == boost::asio::error::try_again)
* {
* // We have to wait for the socket to become ready again.
- * sock_.async_write_some(boost::asio::null_buffers(), *this);
+ * sock_.async_wait(tcp::socket::wait_write, *this);
* return;
* }
*
@@ -1159,7 +1277,7 @@ public:
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
* sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
- * sock.async_write_some(boost::asio::null_buffers(), op);
+ * sock.async_wait(tcp::socket::wait_write, op);
* } @endcode
*/
bool native_non_blocking() const
@@ -1225,7 +1343,7 @@ public:
* || ec == boost::asio::error::try_again)
* {
* // We have to wait for the socket to become ready again.
- * sock_.async_write_some(boost::asio::null_buffers(), *this);
+ * sock_.async_wait(tcp::socket::wait_write, *this);
* return;
* }
*
@@ -1249,7 +1367,7 @@ public:
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
* sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
- * sock.async_write_some(boost::asio::null_buffers(), op);
+ * sock.async_wait(tcp::socket::wait_write, op);
* } @endcode
*/
void native_non_blocking(bool mode)
@@ -1318,7 +1436,7 @@ public:
* || ec == boost::asio::error::try_again)
* {
* // We have to wait for the socket to become ready again.
- * sock_.async_write_some(boost::asio::null_buffers(), *this);
+ * sock_.async_wait(tcp::socket::wait_write, *this);
* return;
* }
*
@@ -1342,14 +1460,15 @@ public:
* void async_sendfile(tcp::socket& sock, int fd, Handler h)
* {
* sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
- * sock.async_write_some(boost::asio::null_buffers(), op);
+ * sock.async_wait(tcp::socket::wait_write, op);
* } @endcode
*/
- boost::system::error_code native_non_blocking(
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, boost::system::error_code& ec)
{
- return this->get_service().native_non_blocking(
+ this->get_service().native_non_blocking(
this->get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint of the socket.
@@ -1362,7 +1481,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
* @endcode
@@ -1387,7 +1506,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
@@ -1412,7 +1531,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
* @endcode
@@ -1437,7 +1556,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
@@ -1464,7 +1583,7 @@ public:
* @par Example
* Shutting down the send side of the socket:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
* @endcode
@@ -1488,7 +1607,7 @@ public:
* @par Example
* Shutting down the send side of the socket:
* @code
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* ...
* boost::system::error_code ec;
* socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
@@ -1498,17 +1617,134 @@ public:
* }
* @endcode
*/
- boost::system::error_code shutdown(shutdown_type what,
+ BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
boost::system::error_code& ec)
{
- return this->get_service().shutdown(this->get_implementation(), what, ec);
+ this->get_service().shutdown(this->get_implementation(), what, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(io_context);
+ * ...
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read);
+ * @endcode
+ */
+ void wait(wait_type w)
+ {
+ boost::system::error_code ec;
+ this->get_service().wait(this->get_implementation(), w, ec);
+ boost::asio::detail::throw_error(ec, "wait");
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(io_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+ {
+ this->get_service().wait(this->get_implementation(), w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the socket to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ /**
+ * This function is used to perform an asynchronous wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param handler The handler to be called when the wait operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void wait_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Wait succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::socket socket(io_context);
+ * ...
+ * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
+ * @endcode
+ */
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_wait(this->get_implementation(),
+ w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_wait(this->get_implementation(),
+ w, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
protected:
/// Protected destructor to prevent deletion through this type.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
~basic_socket()
{
}
+
+private:
+ // Disallow copying and assignment.
+ basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
+ basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
};
} // namespace asio
@@ -1516,4 +1752,8 @@ protected:
#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_BASIC_SOCKET_HPP
diff --git a/boost/asio/basic_socket_acceptor.hpp b/boost/asio/basic_socket_acceptor.hpp
index f1d2b8e7a6..3cbfa5081d 100644
--- a/boost/asio/basic_socket_acceptor.hpp
+++ b/boost/asio/basic_socket_acceptor.hpp
@@ -22,9 +22,27 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/socket_acceptor_service.hpp>
#include <boost/asio/socket_base.hpp>
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/socket_acceptor_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::null_socket_service<Protocol>
+# elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
+# else
+# include <boost/asio/detail/reactive_socket_service.hpp>
+# define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
+# endif
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -42,7 +60,7 @@ namespace asio {
* @par Example
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
* acceptor.open(endpoint.protocol());
* acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
@@ -50,19 +68,22 @@ namespace asio {
* acceptor.listen();
* @endcode
*/
-template <typename Protocol,
- typename SocketAcceptorService = socket_acceptor_service<Protocol> >
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
class basic_socket_acceptor
- : public basic_io_object<SocketAcceptorService>,
+ : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
public socket_base
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of an
- /// acceptor.
- typedef typename SocketAcceptorService::native_handle_type native_type;
+ /// The type of the executor associated with the object.
+ typedef io_context::executor_type executor_type;
/// The native representation of an acceptor.
- typedef typename SocketAcceptorService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -76,12 +97,12 @@ public:
* connections. The open() function must be called before the acceptor can
* accept new socket connections.
*
- * @param io_service The io_service object that the acceptor will use to
+ * @param io_context The io_context object that the acceptor will use to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*/
- explicit basic_socket_acceptor(boost::asio::io_service& io_service)
- : basic_io_object<SocketAcceptorService>(io_service)
+ explicit basic_socket_acceptor(boost::asio::io_context& io_context)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
}
@@ -89,7 +110,7 @@ public:
/**
* This constructor creates an acceptor and automatically opens it.
*
- * @param io_service The io_service object that the acceptor will use to
+ * @param io_context The io_context object that the acceptor will use to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -97,9 +118,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket_acceptor(boost::asio::io_service& io_service,
+ basic_socket_acceptor(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_io_object<SocketAcceptorService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
this->get_service().open(this->get_implementation(), protocol, ec);
@@ -111,7 +132,7 @@ public:
* This constructor creates an acceptor and automatically opens it to listen
* for new connections on the specified endpoint.
*
- * @param io_service The io_service object that the acceptor will use to
+ * @param io_context The io_context object that the acceptor will use to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -125,7 +146,7 @@ public:
*
* @note This constructor is equivalent to the following code:
* @code
- * basic_socket_acceptor<Protocol> acceptor(io_service);
+ * basic_socket_acceptor<Protocol> acceptor(io_context);
* acceptor.open(endpoint.protocol());
* if (reuse_addr)
* acceptor.set_option(socket_base::reuse_address(true));
@@ -133,9 +154,9 @@ public:
* acceptor.listen(listen_backlog);
* @endcode
*/
- basic_socket_acceptor(boost::asio::io_service& io_service,
+ basic_socket_acceptor(boost::asio::io_context& io_context,
const endpoint_type& endpoint, bool reuse_addr = true)
- : basic_io_object<SocketAcceptorService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
const protocol_type protocol = endpoint.protocol();
@@ -150,7 +171,7 @@ public:
this->get_service().bind(this->get_implementation(), endpoint, ec);
boost::asio::detail::throw_error(ec, "bind");
this->get_service().listen(this->get_implementation(),
- socket_base::max_connections, ec);
+ socket_base::max_listen_connections, ec);
boost::asio::detail::throw_error(ec, "listen");
}
@@ -159,7 +180,7 @@ public:
* This constructor creates an acceptor object to hold an existing native
* acceptor.
*
- * @param io_service The io_service object that the acceptor will use to
+ * @param io_context The io_context object that the acceptor will use to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -169,9 +190,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket_acceptor(boost::asio::io_service& io_service,
+ basic_socket_acceptor(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_acceptor)
- : basic_io_object<SocketAcceptorService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
this->get_service().assign(this->get_implementation(),
@@ -188,11 +209,10 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket_acceptor(io_service&) constructor.
+ * constructed using the @c basic_socket_acceptor(io_context&) constructor.
*/
basic_socket_acceptor(basic_socket_acceptor&& other)
- : basic_io_object<SocketAcceptorService>(
- BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other))
+ : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
{
}
@@ -204,17 +224,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket_acceptor(io_service&) constructor.
+ * constructed using the @c basic_socket_acceptor(io_context&) constructor.
*/
basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
{
- basic_io_object<SocketAcceptorService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other));
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
return *this;
}
// All socket acceptors have access to each other's implementations.
- template <typename Protocol1, typename SocketAcceptorService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
friend class basic_socket_acceptor;
/// Move-construct a basic_socket_acceptor from an acceptor of another
@@ -226,13 +245,13 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SocketAcceptorService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_socket_acceptor(
- basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other,
+ basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<SocketAcceptorService>(
+ : basic_io_object<BOOST_ASIO_SVC_T>(
other.get_service(), other.get_implementation())
{
}
@@ -246,21 +265,69 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_service&) constructor.
+ * constructed using the @c basic_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename SocketAcceptorService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_socket_acceptor>::type& operator=(
- basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other)
+ basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket_acceptor tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor<
- Protocol1, SocketAcceptorService1>)(other));
- basic_io_object<SocketAcceptorService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(tmp));
+ basic_socket_acceptor tmp(std::move(other));
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the acceptor.
+ /**
+ * This function destroys the acceptor, cancelling any outstanding
+ * asynchronous operations associated with the acceptor as if by calling
+ * @c cancel.
+ */
+ ~basic_socket_acceptor()
+ {
+ }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_context()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_service()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
/// Open the acceptor using the specified protocol.
/**
* This function opens the socket acceptor so that it will use the specified
@@ -272,7 +339,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* acceptor.open(boost::asio::ip::tcp::v4());
* @endcode
*/
@@ -294,7 +361,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* boost::system::error_code ec;
* acceptor.open(boost::asio::ip::tcp::v4(), ec);
* if (ec)
@@ -303,10 +370,11 @@ public:
* }
* @endcode
*/
- boost::system::error_code open(const protocol_type& protocol,
+ BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
boost::system::error_code& ec)
{
- return this->get_service().open(this->get_implementation(), protocol, ec);
+ this->get_service().open(this->get_implementation(), protocol, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assigns an existing native acceptor to the acceptor.
@@ -338,11 +406,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code assign(const protocol_type& protocol,
+ BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_acceptor, boost::system::error_code& ec)
{
- return this->get_service().assign(this->get_implementation(),
+ this->get_service().assign(this->get_implementation(),
protocol, native_acceptor, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the acceptor is open.
@@ -363,7 +432,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
* acceptor.open(endpoint.protocol());
* acceptor.bind(endpoint);
@@ -388,7 +457,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
* acceptor.open(endpoint.protocol());
* boost::system::error_code ec;
@@ -399,10 +468,11 @@ public:
* }
* @endcode
*/
- boost::system::error_code bind(const endpoint_type& endpoint,
+ BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
boost::system::error_code& ec)
{
- return this->get_service().bind(this->get_implementation(), endpoint, ec);
+ this->get_service().bind(this->get_implementation(), endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Place the acceptor into the state where it will listen for new
@@ -415,7 +485,7 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- void listen(int backlog = socket_base::max_connections)
+ void listen(int backlog = socket_base::max_listen_connections)
{
boost::system::error_code ec;
this->get_service().listen(this->get_implementation(), backlog, ec);
@@ -434,19 +504,20 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::system::error_code ec;
- * acceptor.listen(boost::asio::socket_base::max_connections, ec);
+ * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
* if (ec)
* {
* // An error occurred.
* }
* @endcode
*/
- boost::system::error_code listen(int backlog, boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec)
{
- return this->get_service().listen(this->get_implementation(), backlog, ec);
+ this->get_service().listen(this->get_implementation(), backlog, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Close the acceptor.
@@ -478,7 +549,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::system::error_code ec;
* acceptor.close(ec);
@@ -488,20 +559,62 @@ public:
* }
* @endcode
*/
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return this->get_service().close(this->get_implementation(), ec);
+ this->get_service().close(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
- /// (Deprecated: Use native_handle().) Get the native acceptor representation.
+ /// Release ownership of the underlying native acceptor.
/**
- * 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.
+ * This function causes all outstanding asynchronous accept operations to
+ * finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error. Ownership of the
+ * native acceptor is then transferred to the caller.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
*/
- native_type native()
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release()
{
- return this->get_service().native_handle(this->get_implementation());
+ boost::system::error_code ec;
+ native_handle_type s = this->get_service().release(
+ this->get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "release");
+ return s;
+ }
+
+ /// Release ownership of the underlying native acceptor.
+ /**
+ * This function causes all outstanding asynchronous accept operations to
+ * finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error. Ownership of the
+ * native acceptor is then transferred to the caller.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release(boost::system::error_code& ec)
+ {
+ return this->get_service().release(this->get_implementation(), ec);
}
/// Get the native acceptor representation.
@@ -538,9 +651,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- boost::system::error_code cancel(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- return this->get_service().cancel(this->get_implementation(), ec);
+ this->get_service().cancel(this->get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Set an option on the acceptor.
@@ -558,7 +672,7 @@ public:
* @par Example
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option(true);
* acceptor.set_option(option);
@@ -587,7 +701,7 @@ public:
* @par Example
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option(true);
* boost::system::error_code ec;
@@ -599,11 +713,11 @@ public:
* @endcode
*/
template <typename SettableSocketOption>
- boost::system::error_code set_option(const SettableSocketOption& option,
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
boost::system::error_code& ec)
{
- return this->get_service().set_option(
- this->get_implementation(), option, ec);
+ this->get_service().set_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the acceptor.
@@ -621,7 +735,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option;
* acceptor.get_option(option);
@@ -651,7 +765,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option;
* boost::system::error_code ec;
@@ -664,11 +778,11 @@ public:
* @endcode
*/
template <typename GettableSocketOption>
- boost::system::error_code get_option(GettableSocketOption& option,
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
boost::system::error_code& ec)
{
- return this->get_service().get_option(
- this->get_implementation(), option, ec);
+ this->get_service().get_option(this->get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the acceptor.
@@ -685,7 +799,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
* socket.io_control(command);
@@ -713,7 +827,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
* boost::system::error_code ec;
@@ -725,11 +839,11 @@ public:
* @endcode
*/
template <typename IoControlCommand>
- boost::system::error_code io_control(IoControlCommand& command,
+ BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
boost::system::error_code& ec)
{
- return this->get_service().io_control(
- this->get_implementation(), command, ec);
+ this->get_service().io_control(this->get_implementation(), command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the acceptor.
@@ -781,11 +895,11 @@ public:
* operations. Asynchronous operations will never fail with the error
* boost::asio::error::would_block.
*/
- boost::system::error_code non_blocking(
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(
bool mode, boost::system::error_code& ec)
{
- return this->get_service().non_blocking(
- this->get_implementation(), mode, ec);
+ this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native acceptor implementation.
@@ -845,11 +959,12 @@ public:
* function fails with boost::asio::error::invalid_argument, as the
* combination does not make sense.
*/
- boost::system::error_code native_non_blocking(
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, boost::system::error_code& ec)
{
- return this->get_service().native_non_blocking(
+ this->get_service().native_non_blocking(
this->get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint of the acceptor.
@@ -862,7 +977,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
* @endcode
@@ -888,7 +1003,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
@@ -903,6 +1018,116 @@ public:
return this->get_service().local_endpoint(this->get_implementation(), ec);
}
+ /// Wait for the acceptor to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for an acceptor to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @par Example
+ * Waiting for an acceptor to become readable.
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read);
+ * @endcode
+ */
+ void wait(wait_type w)
+ {
+ boost::system::error_code ec;
+ this->get_service().wait(this->get_implementation(), w, ec);
+ boost::asio::detail::throw_error(ec, "wait");
+ }
+
+ /// Wait for the acceptor to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for an acceptor to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Waiting for an acceptor to become readable.
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::system::error_code ec;
+ * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+ {
+ this->get_service().wait(this->get_implementation(), w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the acceptor to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ /**
+ * This function is used to perform an asynchronous wait for an acceptor to
+ * enter a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @param handler The handler to be called when the wait operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void wait_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Wait succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * acceptor.async_wait(
+ * boost::asio::ip::tcp::acceptor::wait_read,
+ * wait_handler);
+ * @endcode
+ */
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_wait(this->get_implementation(),
+ w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_wait(this->get_implementation(),
+ w, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Accept a new connection.
/**
* This function is used to accept a new connection from a peer into the
@@ -915,15 +1140,21 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* acceptor.accept(socket);
* @endcode
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename Protocol1, typename SocketService>
void accept(basic_socket<Protocol1, SocketService>& peer,
typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ template <typename Protocol1>
+ void accept(basic_socket<Protocol1>& peer,
+ typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
boost::system::error_code ec;
this->get_service().accept(this->get_implementation(),
@@ -943,9 +1174,9 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
- * boost::asio::ip::tcp::soocket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::system::error_code ec;
* acceptor.accept(socket, ec);
* if (ec)
@@ -954,14 +1185,22 @@ public:
* }
* @endcode
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename Protocol1, typename SocketService>
- boost::system::error_code accept(
+ BOOST_ASIO_SYNC_OP_VOID accept(
basic_socket<Protocol1, SocketService>& peer,
boost::system::error_code& ec,
typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ template <typename Protocol1>
+ BOOST_ASIO_SYNC_OP_VOID accept(
+ basic_socket<Protocol1>& peer, boost::system::error_code& ec,
+ typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
- return this->get_service().accept(this->get_implementation(),
+ this->get_service().accept(this->get_implementation(),
peer, static_cast<endpoint_type*>(0), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous accept.
@@ -982,7 +1221,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* @code
@@ -996,26 +1235,45 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* acceptor.async_accept(socket, accept_handler);
* @endcode
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename Protocol1, typename SocketService, typename AcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code))
async_accept(basic_socket<Protocol1, SocketService>& peer,
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ template <typename Protocol1, typename AcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+ void (boost::system::error_code))
+ async_accept(basic_socket<Protocol1>& peer,
+ BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+ typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_accept(this->get_implementation(),
peer, static_cast<endpoint_type*>(0),
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<AcceptHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_accept(this->get_implementation(),
+ peer, static_cast<endpoint_type*>(0), init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Accept a new connection and obtain the endpoint of the peer
@@ -1034,16 +1292,20 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::asio::ip::tcp::endpoint endpoint;
* acceptor.accept(socket, endpoint);
* @endcode
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename SocketService>
void accept(basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ void accept(basic_socket<protocol_type>& peer, endpoint_type& peer_endpoint)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
boost::system::error_code ec;
this->get_service().accept(this->get_implementation(),
@@ -1067,9 +1329,9 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_service);
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_service);
+ * boost::asio::ip::tcp::socket socket(io_context);
* boost::asio::ip::tcp::endpoint endpoint;
* boost::system::error_code ec;
* acceptor.accept(socket, endpoint, ec);
@@ -1079,13 +1341,19 @@ public:
* }
* @endcode
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename SocketService>
- boost::system::error_code accept(
+ BOOST_ASIO_SYNC_OP_VOID accept(
basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, boost::system::error_code& ec)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
- return this->get_service().accept(
+ this->get_service().accept(
this->get_implementation(), peer, &peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous accept.
@@ -1112,21 +1380,600 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
template <typename SocketService, typename AcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code))
async_accept(basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ template <typename AcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+ void (boost::system::error_code))
+ async_accept(basic_socket<protocol_type>& peer,
+ endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_accept(this->get_implementation(), peer,
&peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<AcceptHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_accept(this->get_implementation(),
+ peer, &peer_endpoint, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ typename Protocol::socket accept()
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(
+ this->get_service().accept(
+ this->get_implementation(), 0, 0, ec));
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(boost::system::error_code& ec)
+ {
+ return this->get_service().accept(this->get_implementation(), 0, 0, ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * 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.
+ *
+ * @param 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:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * acceptor.async_accept(accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+ handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_accept(
+ this->get_implementation(), static_cast<boost::asio::io_context*>(0),
+ static_cast<endpoint_type*>(0),
+ BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket)> init(handler);
+
+ this->get_service().async_accept(
+ this->get_implementation(), static_cast<boost::asio::io_context*>(0),
+ static_cast<endpoint_type*>(0), init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ typename Protocol::socket accept(boost::asio::io_context& io_context)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(
+ this->get_service().accept(this->get_implementation(),
+ &io_context, static_cast<endpoint_type*>(0), ec));
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
}
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(
+ boost::asio::io_context& io_context, boost::system::error_code& ec)
+ {
+ return this->get_service().accept(this->get_implementation(),
+ &io_context, static_cast<endpoint_type*>(0), ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @param 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:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * acceptor.async_accept(io_context2, accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(boost::asio::io_context& io_context,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+ handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_accept(this->get_implementation(),
+ &io_context, static_cast<endpoint_type*>(0),
+ BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket)> init(handler);
+
+ this->get_service().async_accept(this->get_implementation(),
+ &io_context, static_cast<endpoint_type*>(0), init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
+ * @endcode
+ */
+ typename Protocol::socket accept(endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(
+ this->get_service().accept(this->get_implementation(),
+ static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec));
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(
+ endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ return this->get_service().accept(this->get_implementation(),
+ static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * 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.
+ *
+ * @param 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.
+ *
+ * @param 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:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+ handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_accept(this->get_implementation(),
+ static_cast<boost::asio::io_context*>(0), &peer_endpoint,
+ BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket)> init(handler);
+
+ this->get_service().async_accept(this->get_implementation(),
+ static_cast<boost::asio::io_context*>(0), &peer_endpoint,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(io_context2, endpoint));
+ * @endcode
+ */
+ typename Protocol::socket accept(
+ boost::asio::io_context& io_context, endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(
+ this->get_service().accept(this->get_implementation(),
+ &io_context, &peer_endpoint, ec));
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(io_context2, endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(boost::asio::io_context& io_context,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ return this->get_service().accept(this->get_implementation(),
+ &io_context, &peer_endpoint, ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * 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.
+ *
+ * @param io_context The io_context object to be used for the newly accepted
+ * socket.
+ *
+ * @param 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.
+ *
+ * @param 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:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(io_context2, endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(boost::asio::io_context& io_context,
+ endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+ handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_accept(
+ this->get_implementation(), &io_context, &peer_endpoint,
+ BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket)> init(handler);
+
+ this->get_service().async_accept(this->get_implementation(),
+ &io_context, &peer_endpoint, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
};
} // namespace asio
@@ -1134,4 +1981,8 @@ public:
#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
diff --git a/boost/asio/basic_socket_iostream.hpp b/boost/asio/basic_socket_iostream.hpp
index 6ed71f7b68..a5f8e0223a 100644
--- a/boost/asio/basic_socket_iostream.hpp
+++ b/boost/asio/basic_socket_iostream.hpp
@@ -22,7 +22,10 @@
#include <istream>
#include <ostream>
#include <boost/asio/basic_socket_streambuf.hpp>
-#include <boost/asio/stream_socket_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
@@ -33,8 +36,8 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>(
// &this->detail::socket_iostream_base<
-// Protocol, StreamSocketService, Time,
-// TimeTraits, TimerService>::streambuf_)
+// Protocol BOOST_ASIO_SVC_TARG, Clock,
+// WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit);
@@ -43,14 +46,14 @@
# define BOOST_ASIO_PRIVATE_CTR_DEF(n) \
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
- explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_PARAMS(n)) \
+ explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \
- Protocol, StreamSocketService, Time, \
- TimeTraits, TimerService>::streambuf_) \
+ Protocol BOOST_ASIO_SVC_TARG, Clock, \
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_) \
{ \
this->setf(std::ios_base::unitbuf); \
- if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \
+ if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
this->setstate(std::ios_base::failbit); \
} \
/**/
@@ -66,9 +69,9 @@
# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
- void connect(BOOST_ASIO_VARIADIC_PARAMS(n)) \
+ void connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
{ \
- if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \
+ if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
this->setstate(std::ios_base::failbit); \
} \
/**/
@@ -83,69 +86,163 @@ namespace detail {
// A separate base class is used to ensure that the streambuf is initialised
// prior to the basic_socket_iostream's basic_iostream base class.
-template <typename Protocol, typename StreamSocketService,
- typename Time, typename TimeTraits, typename TimerService>
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
class socket_iostream_base
{
protected:
- basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService> streambuf_;
+ socket_iostream_base()
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ socket_iostream_base(socket_iostream_base&& other)
+ : streambuf_(std::move(other.streambuf_))
+ {
+ }
+
+ socket_iostream_base(basic_stream_socket<Protocol> s)
+ : streambuf_(std::move(s))
+ {
+ }
+
+ socket_iostream_base& operator=(socket_iostream_base&& other)
+ {
+ streambuf_ = std::move(other.streambuf_);
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+ Clock, WaitTraits BOOST_ASIO_SVC_TARG1> streambuf_;
};
-}
+} // namespace detail
-/// Iostream interface for a socket.
-template <typename Protocol,
- typename StreamSocketService = stream_socket_service<Protocol>,
-#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
- || defined(GENERATING_DOCUMENTATION)
- typename Time = boost::posix_time::ptime,
- typename TimeTraits = boost::asio::time_traits<Time>,
- typename TimerService = deadline_timer_service<Time, TimeTraits> >
+#if !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+ typename Clock = boost::posix_time::ptime,
+ typename WaitTraits = time_traits<Clock>
+ BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
- typename Time = steady_timer::clock_type,
- typename TimeTraits = steady_timer::traits_type,
- typename TimerService = steady_timer::service_type>
+ typename Clock = chrono::steady_clock,
+ typename WaitTraits = wait_traits<Clock>
+ BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
+class basic_socket_iostream;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
+
+/// Iostream interface for a socket.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Protocol,
+ typename Clock = chrono::steady_clock,
+ typename WaitTraits = wait_traits<Clock> >
+#else // defined(GENERATING_DOCUMENTATION)
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream
- : private detail::socket_iostream_base<Protocol,
- StreamSocketService, Time, TimeTraits, TimerService>,
+ : private detail::socket_iostream_base<Protocol
+ BOOST_ASIO_SVC_TARG, Clock, WaitTraits BOOST_ASIO_SVC_TARG1>,
public std::basic_iostream<char>
{
private:
// These typedefs are intended keep this class's implementation independent
- // of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
+ // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
- typedef TimeTraits traits_helper;
+ typedef WaitTraits traits_helper;
#else
- typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
+ typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
public:
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
+ /// The clock type.
+ typedef Clock clock_type;
+
#if defined(GENERATING_DOCUMENTATION)
+ /// (Deprecated: Use time_point.) The time type.
+ typedef typename WaitTraits::time_type time_type;
+
/// The time type.
- typedef typename TimeTraits::time_type time_type;
+ typedef typename WaitTraits::time_point time_point;
+
+ /// (Deprecated: Use duration.) The duration type.
+ typedef typename WaitTraits::duration_type duration_type;
/// The duration type.
- typedef typename TimeTraits::duration_type duration_type;
+ typedef typename WaitTraits::duration duration;
#else
+# if !defined(BOOST_ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_type;
typedef typename traits_helper::duration_type duration_type;
+# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+ typedef typename traits_helper::time_type time_point;
+ typedef typename traits_helper::duration_type duration;
#endif
/// Construct a basic_socket_iostream without establishing a connection.
basic_socket_iostream()
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
- Protocol, StreamSocketService, Time,
- TimeTraits, TimerService>::streambuf_)
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+ {
+ this->setf(std::ios_base::unitbuf);
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Construct a basic_socket_iostream from the supplied socket.
+ explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
+ : detail::socket_iostream_base<
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(s)),
+ std::basic_iostream<char>(
+ &this->detail::socket_iostream_base<
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
+#if defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE) \
+ || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_socket_iostream from another.
+ basic_socket_iostream(basic_socket_iostream&& other)
+ : detail::socket_iostream_base<
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(other)),
+ std::basic_iostream<char>(std::move(other))
+ {
+ this->set_rdbuf(&this->detail::socket_iostream_base<
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+ }
+
+ /// Move-assign a basic_socket_iostream from another.
+ basic_socket_iostream& operator=(basic_socket_iostream&& other)
+ {
+ std::basic_iostream<char>::operator=(std::move(other));
+ detail::socket_iostream_base<
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::operator=(std::move(other));
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
+ // || defined(GENERATING_DOCUMENTATION)
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection to an endpoint corresponding to a resolver query.
/**
@@ -160,8 +257,8 @@ public:
explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
- Protocol, StreamSocketService, Time,
- TimeTraits, TimerService>::streambuf_)
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0)
@@ -199,14 +296,20 @@ public:
}
/// Return a pointer to the underlying streambuf.
- basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService>* rdbuf() const
+ basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+ Clock, WaitTraits BOOST_ASIO_SVC_TARG1>* rdbuf() const
{
- return const_cast<basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService>*>(
+ return const_cast<basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+ Clock, WaitTraits BOOST_ASIO_SVC_TARG1>*>(
&this->detail::socket_iostream_base<
- Protocol, StreamSocketService, Time,
- TimeTraits, TimerService>::streambuf_);
+ Protocol BOOST_ASIO_SVC_TARG, Clock,
+ WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+ }
+
+ /// Get a reference to the underlying socket.
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+ {
+ return rdbuf()->socket();
}
/// Get the last error associated with the stream.
@@ -223,17 +326,29 @@ public:
*/
const boost::system::error_code& error() const
{
- return rdbuf()->puberror();
+ return rdbuf()->error();
}
- /// Get the stream's expiry time as an absolute time.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute
+ /// time.
/**
* @return An absolute time value representing the stream's expiry time.
*/
- time_type expires_at() const
+ time_point expires_at() const
{
return rdbuf()->expires_at();
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the stream's expiry time as an absolute time.
+ /**
+ * @return An absolute time value representing the stream's expiry time.
+ */
+ time_point expiry() const
+ {
+ return rdbuf()->expiry();
+ }
/// Set the stream's expiry time as an absolute time.
/**
@@ -244,21 +359,37 @@ public:
*
* @param expiry_time The expiry time to be used for the stream.
*/
- void expires_at(const time_type& expiry_time)
+ void expires_at(const time_point& expiry_time)
{
rdbuf()->expires_at(expiry_time);
}
- /// Get the timer's expiry time relative to now.
+ /// Set the stream's expiry time relative to now.
+ /**
+ * 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
+ * boost::asio::error::operation_aborted.
+ *
+ * @param expiry_time The expiry time to be used for the timer.
+ */
+ void expires_after(const duration& expiry_time)
+ {
+ rdbuf()->expires_after(expiry_time);
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now.
/**
* @return A relative time value representing the stream's expiry time.
*/
- duration_type expires_from_now() const
+ duration expires_from_now() const
{
return rdbuf()->expires_from_now();
}
- /// Set the stream's expiry time relative to now.
+ /// (Deprecated: Use expires_after().) Set the stream's expiry time relative
+ /// to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
@@ -267,10 +398,17 @@ public:
*
* @param expiry_time The expiry time to be used for the timer.
*/
- void expires_from_now(const duration_type& expiry_time)
+ void expires_from_now(const duration& expiry_time)
{
rdbuf()->expires_from_now(expiry_time);
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+private:
+ // Disallow copying and assignment.
+ basic_socket_iostream(const basic_socket_iostream&) BOOST_ASIO_DELETED;
+ basic_socket_iostream& operator=(
+ const basic_socket_iostream&) BOOST_ASIO_DELETED;
};
} // namespace asio
diff --git a/boost/asio/basic_socket_streambuf.hpp b/boost/asio/basic_socket_streambuf.hpp
index 922b005d88..352225b876 100644
--- a/boost/asio/basic_socket_streambuf.hpp
+++ b/boost/asio/basic_socket_streambuf.hpp
@@ -20,15 +20,24 @@
#if !defined(BOOST_ASIO_NO_IOSTREAM)
#include <streambuf>
+#include <vector>
#include <boost/asio/basic_socket.hpp>
-#include <boost/asio/deadline_timer_service.hpp>
-#include <boost/asio/detail/array.hpp>
+#include <boost/asio/basic_stream_socket.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/stream_socket_service.hpp>
+#include <boost/asio/io_context.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
-# include <boost/asio/deadline_timer.hpp>
+# if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/deadline_timer_service.hpp>
+# else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/deadline_timer_service.hpp>
+# endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#else
# include <boost/asio/steady_timer.hpp>
#endif
@@ -39,113 +48,214 @@
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
-// basic_socket_streambuf<Protocol, StreamSocketService,
-// Time, TimeTraits, TimerService>* connect(
-// T1 x1, ..., Tn xn)
+// basic_socket_streambuf* connect(T1 x1, ..., Tn xn)
// {
// init_buffers();
-// this->basic_socket<Protocol, StreamSocketService>::close(ec_);
// typedef typename Protocol::resolver resolver_type;
-// typedef typename resolver_type::query resolver_query;
-// resolver_query query(x1, ..., xn);
-// resolve_and_connect(query);
+// resolver_type resolver(socket().get_executor().context());
+// connect_to_endpoints(
+// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
// }
// This macro should only persist within this file.
# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
- basic_socket_streambuf<Protocol, StreamSocketService, \
- Time, TimeTraits, TimerService>* connect(BOOST_ASIO_VARIADIC_PARAMS(n)) \
+ basic_socket_streambuf* connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
{ \
init_buffers(); \
- this->basic_socket<Protocol, StreamSocketService>::close(ec_); \
typedef typename Protocol::resolver resolver_type; \
- typedef typename resolver_type::query resolver_query; \
- resolver_query query(BOOST_ASIO_VARIADIC_ARGS(n)); \
- resolve_and_connect(query); \
+ resolver_type resolver(socket().get_executor().context()); \
+ connect_to_endpoints( \
+ resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
} \
/**/
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# define BOOST_ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
-// A separate base class is used to ensure that the io_service is initialised
-// prior to the basic_socket_streambuf's basic_socket base class.
-class socket_streambuf_base
+// A separate base class is used to ensure that the io_context member is
+// initialised prior to the basic_socket_streambuf's basic_socket base class.
+class socket_streambuf_io_context
+{
+protected:
+ socket_streambuf_io_context(io_context* ctx)
+ : default_io_context_(ctx)
+ {
+ }
+
+ shared_ptr<io_context> default_io_context_;
+};
+
+// A separate base class is used to ensure that the dynamically allocated
+// buffers are constructed prior to the basic_socket_streambuf's basic_socket
+// base class. This makes moving the socket is the last potentially throwing
+// step in the streambuf's move constructor, giving the constructor a strong
+// exception safety guarantee.
+class socket_streambuf_buffers
{
protected:
- io_service io_service_;
+ socket_streambuf_buffers()
+ : get_buffer_(buffer_size),
+ put_buffer_(buffer_size)
+ {
+ }
+
+ enum { buffer_size = 512 };
+ std::vector<char> get_buffer_;
+ std::vector<char> put_buffer_;
};
} // namespace detail
-/// Iostream streambuf for a socket.
-template <typename Protocol,
- typename StreamSocketService = stream_socket_service<Protocol>,
-#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
- || defined(GENERATING_DOCUMENTATION)
- typename Time = boost::posix_time::ptime,
- typename TimeTraits = boost::asio::time_traits<Time>,
- typename TimerService = deadline_timer_service<Time, TimeTraits> >
+#if !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+ typename Clock = boost::posix_time::ptime,
+ typename WaitTraits = time_traits<Clock>
+ BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
- typename Time = steady_timer::clock_type,
- typename TimeTraits = steady_timer::traits_type,
- typename TimerService = steady_timer::service_type>
+ typename Clock = chrono::steady_clock,
+ typename WaitTraits = wait_traits<Clock>
+ BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
+class basic_socket_streambuf;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
+
+/// Iostream streambuf for a socket.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Protocol,
+ typename Clock = chrono::steady_clock,
+ typename WaitTraits = wait_traits<Clock> >
+#else // defined(GENERATING_DOCUMENTATION)
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf
: public std::streambuf,
- private detail::socket_streambuf_base,
- public basic_socket<Protocol, StreamSocketService>
+ private detail::socket_streambuf_io_context,
+ private detail::socket_streambuf_buffers,
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ private basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+ public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
private:
// These typedefs are intended keep this class's implementation independent
- // of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
+ // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
- typedef TimeTraits traits_helper;
+ typedef WaitTraits traits_helper;
#else
- typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
+ typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
public:
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
+ /// The clock type.
+ typedef Clock clock_type;
+
#if defined(GENERATING_DOCUMENTATION)
+ /// (Deprecated: Use time_point.) The time type.
+ typedef typename WaitTraits::time_type time_type;
+
/// The time type.
- typedef typename TimeTraits::time_type time_type;
+ typedef typename WaitTraits::time_point time_point;
+
+ /// (Deprecated: Use duration.) The duration type.
+ typedef typename WaitTraits::duration_type duration_type;
/// The duration type.
- typedef typename TimeTraits::duration_type duration_type;
+ typedef typename WaitTraits::duration duration;
#else
+# if !defined(BOOST_ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_type;
typedef typename traits_helper::duration_type duration_type;
+# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+ typedef typename traits_helper::time_type time_point;
+ typedef typename traits_helper::duration_type duration;
#endif
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
- : basic_socket<Protocol, StreamSocketService>(
- this->detail::socket_streambuf_base::io_service_),
- unbuffered_(false),
- timer_service_(0),
- timer_state_(no_timer)
+ : detail::socket_streambuf_io_context(new io_context),
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>(*default_io_context_),
+ expiry_time_(max_expiry_time())
+ {
+ init_buffers();
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Construct a basic_socket_streambuf from the supplied socket.
+ explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
+ : detail::socket_streambuf_io_context(0),
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(s)),
+ expiry_time_(max_expiry_time())
{
init_buffers();
}
+ /// Move-construct a basic_socket_streambuf from another.
+ basic_socket_streambuf(basic_socket_streambuf&& other)
+ : detail::socket_streambuf_io_context(other),
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other.socket())),
+ ec_(other.ec_),
+ expiry_time_(other.expiry_time_)
+ {
+ get_buffer_.swap(other.get_buffer_);
+ put_buffer_.swap(other.put_buffer_);
+ setg(other.eback(), other.gptr(), other.egptr());
+ setp(other.pptr(), other.epptr());
+ other.ec_ = boost::system::error_code();
+ other.expiry_time_ = max_expiry_time();
+ other.init_buffers();
+ }
+
+ /// Move-assign a basic_socket_streambuf from another.
+ basic_socket_streambuf& operator=(basic_socket_streambuf&& other)
+ {
+ this->close();
+ socket() = std::move(other.socket());
+ detail::socket_streambuf_io_context::operator=(other);
+ ec_ = other.ec_;
+ expiry_time_ = other.expiry_time_;
+ get_buffer_.swap(other.get_buffer_);
+ put_buffer_.swap(other.put_buffer_);
+ setg(other.eback(), other.gptr(), other.egptr());
+ setp(other.pptr(), other.epptr());
+ other.ec_ = boost::system::error_code();
+ other.expiry_time_ = max_expiry_time();
+ other.put_buffer_.resize(buffer_size);
+ other.init_buffers();
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
/// Destructor flushes buffered data.
virtual ~basic_socket_streambuf()
{
if (pptr() != pbase())
overflow(traits_type::eof());
-
- destroy_timer();
}
/// Establish a connection.
@@ -155,29 +265,11 @@ public:
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
- basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService>* connect(
- const endpoint_type& endpoint)
+ basic_socket_streambuf* connect(const endpoint_type& endpoint)
{
init_buffers();
-
- this->basic_socket<Protocol, StreamSocketService>::close(ec_);
-
- if (timer_state_ == timer_has_expired)
- {
- ec_ = boost::asio::error::operation_aborted;
- return 0;
- }
-
- io_handler handler = { this };
- this->basic_socket<Protocol, StreamSocketService>::async_connect(
- endpoint, handler);
-
- ec_ = boost::asio::error::would_block;
- this->get_service().get_io_service().reset();
- do this->get_service().get_io_service().run_one();
- while (ec_ == boost::asio::error::would_block);
-
+ ec_ = boost::system::error_code();
+ this->connect_to_endpoints(&endpoint, &endpoint + 1);
return !ec_ ? this : 0;
}
@@ -192,19 +284,15 @@ public:
* pointer otherwise.
*/
template <typename T1, ..., typename TN>
- basic_socket_streambuf<Protocol, StreamSocketService>* connect(
- T1 t1, ..., TN tn);
+ basic_socket_streambuf* connect(T1 t1, ..., TN tn);
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... T>
- basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService>* connect(T... x)
+ basic_socket_streambuf* connect(T... x)
{
init_buffers();
- this->basic_socket<Protocol, StreamSocketService>::close(ec_);
typedef typename Protocol::resolver resolver_type;
- typedef typename resolver_type::query resolver_query;
- resolver_query query(x...);
- resolve_and_connect(query);
+ resolver_type resolver(socket().get_executor().context());
+ connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0;
}
#else
@@ -216,36 +304,63 @@ public:
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
- basic_socket_streambuf<Protocol, StreamSocketService,
- Time, TimeTraits, TimerService>* close()
+ basic_socket_streambuf* close()
{
sync();
- this->basic_socket<Protocol, StreamSocketService>::close(ec_);
+ socket().close(ec_);
if (!ec_)
init_buffers();
return !ec_ ? this : 0;
}
+ /// Get a reference to the underlying socket.
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+ {
+ return *this;
+ }
+
/// Get the last error associated with the stream buffer.
/**
* @return An \c error_code corresponding to the last error from the stream
* buffer.
*/
+ const boost::system::error_code& error() const
+ {
+ return ec_;
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use error().) Get the last error associated with the stream
+ /// buffer.
+ /**
+ * @return An \c error_code corresponding to the last error from the stream
+ * buffer.
+ */
const boost::system::error_code& puberror() const
{
return error();
}
+ /// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an
+ /// absolute time.
+ /**
+ * @return An absolute time value representing the stream buffer's expiry
+ * time.
+ */
+ time_point expires_at() const
+ {
+ return expiry_time_;
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
/// Get the stream buffer's expiry time as an absolute time.
/**
* @return An absolute time value representing the stream buffer's expiry
* time.
*/
- time_type expires_at() const
+ time_point expiry() const
{
- return timer_service_
- ? timer_service_->expires_at(timer_implementation_)
- : time_type();
+ return expiry_time_;
}
/// Set the stream buffer's expiry time as an absolute time.
@@ -257,27 +372,38 @@ public:
*
* @param expiry_time The expiry time to be used for the stream.
*/
- void expires_at(const time_type& expiry_time)
+ void expires_at(const time_point& expiry_time)
{
- construct_timer();
-
- boost::system::error_code ec;
- timer_service_->expires_at(timer_implementation_, expiry_time, ec);
- boost::asio::detail::throw_error(ec, "expires_at");
+ expiry_time_ = expiry_time;
+ }
- start_timer();
+ /// Set the stream buffer's expiry time relative to now.
+ /**
+ * 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
+ * boost::asio::error::operation_aborted.
+ *
+ * @param expiry_time The expiry time to be used for the timer.
+ */
+ void expires_after(const duration& expiry_time)
+ {
+ expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
}
- /// Get the stream buffer's expiry time relative to now.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative
+ /// to now.
/**
* @return A relative time value representing the stream buffer's expiry time.
*/
- duration_type expires_from_now() const
+ duration expires_from_now() const
{
return traits_helper::subtract(expires_at(), traits_helper::now());
}
- /// Set the stream buffer's expiry time relative to now.
+ /// (Deprecated: Use expires_after().) Set the stream buffer's expiry time
+ /// relative to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
@@ -286,109 +412,126 @@ public:
*
* @param expiry_time The expiry time to be used for the timer.
*/
- void expires_from_now(const duration_type& expiry_time)
+ void expires_from_now(const duration& expiry_time)
{
- construct_timer();
-
- boost::system::error_code ec;
- timer_service_->expires_from_now(timer_implementation_, expiry_time, ec);
- boost::asio::detail::throw_error(ec, "expires_from_now");
-
- start_timer();
+ expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
protected:
int_type underflow()
{
- if (gptr() == egptr())
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ ec_ = boost::asio::error::operation_not_supported;
+ return traits_type::eof();
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ if (gptr() != egptr())
+ return traits_type::eof();
+
+ for (;;)
{
- if (timer_state_ == timer_has_expired)
+ // Check if we are past the expiry time.
+ if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
- ec_ = boost::asio::error::operation_aborted;
+ ec_ = boost::asio::error::timed_out;
return traits_type::eof();
}
- io_handler handler = { this };
- this->get_service().async_receive(this->get_implementation(),
- boost::asio::buffer(boost::asio::buffer(get_buffer_) + putback_max),
- 0, handler);
+ // Try to complete the operation without blocking.
+ if (!socket().native_non_blocking())
+ socket().native_non_blocking(true, ec_);
+ detail::buffer_sequence_adapter<mutable_buffer, mutable_buffer>
+ bufs(boost::asio::buffer(get_buffer_) + putback_max);
+ detail::signed_size_type bytes = detail::socket_ops::recv(
+ socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
- ec_ = boost::asio::error::would_block;
- this->get_service().get_io_service().reset();
- do this->get_service().get_io_service().run_one();
- while (ec_ == boost::asio::error::would_block);
- if (ec_)
+ // Check if operation succeeded.
+ if (bytes > 0)
+ {
+ setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
+ &get_buffer_[0] + putback_max + bytes);
+ return traits_type::to_int_type(*gptr());
+ }
+
+ // Check for EOF.
+ if (bytes == 0)
+ {
+ ec_ = boost::asio::error::eof;
return traits_type::eof();
+ }
- setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
- &get_buffer_[0] + putback_max + bytes_transferred_);
- return traits_type::to_int_type(*gptr());
- }
- else
- {
- return traits_type::eof();
+ // Operation failed.
+ if (ec_ != boost::asio::error::would_block
+ && ec_ != boost::asio::error::try_again)
+ return traits_type::eof();
+
+ // Wait for socket to become ready.
+ if (detail::socket_ops::poll_read(
+ socket().native_handle(), 0, timeout(), ec_) < 0)
+ return traits_type::eof();
}
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
}
int_type overflow(int_type c)
{
- if (unbuffered_)
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ ec_ = boost::asio::error::operation_not_supported;
+ return traits_type::eof();
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ char_type ch = traits_type::to_char_type(c);
+
+ // Determine what needs to be sent.
+ const_buffer output_buffer;
+ if (put_buffer_.empty())
{
if (traits_type::eq_int_type(c, traits_type::eof()))
+ return traits_type::not_eof(c); // Nothing to do.
+ output_buffer = boost::asio::buffer(&ch, sizeof(char_type));
+ }
+ else
+ {
+ output_buffer = boost::asio::buffer(pbase(),
+ (pptr() - pbase()) * sizeof(char_type));
+ }
+
+ while (output_buffer.size() > 0)
+ {
+ // Check if we are past the expiry time.
+ if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
- // Nothing to do.
- return traits_type::not_eof(c);
+ ec_ = boost::asio::error::timed_out;
+ return traits_type::eof();
}
- else
+
+ // Try to complete the operation without blocking.
+ if (!socket().native_non_blocking())
+ socket().native_non_blocking(true, ec_);
+ detail::buffer_sequence_adapter<
+ const_buffer, const_buffer> bufs(output_buffer);
+ detail::signed_size_type bytes = detail::socket_ops::send(
+ socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
+
+ // Check if operation succeeded.
+ if (bytes > 0)
{
- if (timer_state_ == timer_has_expired)
- {
- ec_ = boost::asio::error::operation_aborted;
- return traits_type::eof();
- }
-
- // Send the single character immediately.
- char_type ch = traits_type::to_char_type(c);
- io_handler handler = { this };
- this->get_service().async_send(this->get_implementation(),
- boost::asio::buffer(&ch, sizeof(char_type)), 0, handler);
-
- ec_ = boost::asio::error::would_block;
- this->get_service().get_io_service().reset();
- do this->get_service().get_io_service().run_one();
- while (ec_ == boost::asio::error::would_block);
- if (ec_)
- return traits_type::eof();
-
- return c;
+ output_buffer += static_cast<std::size_t>(bytes);
+ continue;
}
+
+ // Operation failed.
+ if (ec_ != boost::asio::error::would_block
+ && ec_ != boost::asio::error::try_again)
+ return traits_type::eof();
+
+ // Wait for socket to become ready.
+ if (detail::socket_ops::poll_write(
+ socket().native_handle(), 0, timeout(), ec_) < 0)
+ return traits_type::eof();
}
- else
+
+ if (!put_buffer_.empty())
{
- // Send all data in the output buffer.
- boost::asio::const_buffer buffer =
- boost::asio::buffer(pbase(), pptr() - pbase());
- while (boost::asio::buffer_size(buffer) > 0)
- {
- if (timer_state_ == timer_has_expired)
- {
- ec_ = boost::asio::error::operation_aborted;
- return traits_type::eof();
- }
-
- io_handler handler = { this };
- this->get_service().async_send(this->get_implementation(),
- boost::asio::buffer(buffer), 0, handler);
-
- ec_ = boost::asio::error::would_block;
- this->get_service().get_io_service().reset();
- do this->get_service().get_io_service().run_one();
- while (ec_ == boost::asio::error::would_block);
- if (ec_)
- return traits_type::eof();
-
- buffer = buffer + bytes_transferred_;
- }
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
// If the new character is eof then our work here is done.
@@ -396,10 +539,12 @@ protected:
return traits_type::not_eof(c);
// Add the new character to the output buffer.
- *pptr() = traits_type::to_char_type(c);
+ *pptr() = ch;
pbump(1);
- return c;
}
+
+ return c;
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
}
int sync()
@@ -411,148 +556,127 @@ protected:
{
if (pptr() == pbase() && s == 0 && n == 0)
{
- unbuffered_ = true;
+ put_buffer_.clear();
setp(0, 0);
+ sync();
return this;
}
return 0;
}
- /// Get the last error associated with the stream buffer.
- /**
- * @return An \c error_code corresponding to the last error from the stream
- * buffer.
- */
- virtual const boost::system::error_code& error() const
- {
- return ec_;
- }
-
private:
+ // Disallow copying and assignment.
+ basic_socket_streambuf(const basic_socket_streambuf&) BOOST_ASIO_DELETED;
+ basic_socket_streambuf& operator=(
+ const basic_socket_streambuf&) BOOST_ASIO_DELETED;
+
void init_buffers()
{
setg(&get_buffer_[0],
&get_buffer_[0] + putback_max,
&get_buffer_[0] + putback_max);
- if (unbuffered_)
+
+ if (put_buffer_.empty())
setp(0, 0);
else
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
}
- template <typename ResolverQuery>
- void resolve_and_connect(const ResolverQuery& query)
+ int timeout() const
{
- typedef typename Protocol::resolver resolver_type;
- typedef typename resolver_type::iterator iterator_type;
- resolver_type resolver(detail::socket_streambuf_base::io_service_);
- iterator_type i = resolver.resolve(query, ec_);
- if (!ec_)
- {
- iterator_type end;
- ec_ = boost::asio::error::host_not_found;
- while (ec_ && i != end)
- {
- this->basic_socket<Protocol, StreamSocketService>::close(ec_);
-
- if (timer_state_ == timer_has_expired)
- {
- ec_ = boost::asio::error::operation_aborted;
- return;
- }
-
- io_handler handler = { this };
- this->basic_socket<Protocol, StreamSocketService>::async_connect(
- *i, handler);
-
- ec_ = boost::asio::error::would_block;
- this->get_service().get_io_service().reset();
- do this->get_service().get_io_service().run_one();
- while (ec_ == boost::asio::error::would_block);
-
- ++i;
- }
- }
+ int64_t msec = traits_helper::to_posix_duration(
+ traits_helper::subtract(expiry_time_,
+ traits_helper::now())).total_milliseconds();
+ if (msec > (std::numeric_limits<int>::max)())
+ msec = (std::numeric_limits<int>::max)();
+ else if (msec < 0)
+ msec = 0;
+ return static_cast<int>(msec);
}
- struct io_handler;
- friend struct io_handler;
- struct io_handler
+ template <typename EndpointSequence>
+ void connect_to_endpoints(const EndpointSequence& endpoints)
{
- basic_socket_streambuf* this_;
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred = 0)
- {
- this_->ec_ = ec;
- this_->bytes_transferred_ = bytes_transferred;
- }
- };
+ this->connect_to_endpoints(endpoints.begin(), endpoints.end());
+ }
- struct timer_handler;
- friend struct timer_handler;
- struct timer_handler
+ template <typename EndpointIterator>
+ void connect_to_endpoints(EndpointIterator begin, EndpointIterator end)
{
- basic_socket_streambuf* this_;
-
- void operator()(const boost::system::error_code&)
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ ec_ = boost::asio::error::operation_not_supported;
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ if (ec_)
+ return;
+
+ ec_ = boost::asio::error::not_found;
+ for (EndpointIterator i = begin; i != end; ++i)
{
- time_type now = traits_helper::now();
-
- time_type expiry_time = this_->timer_service_->expires_at(
- this_->timer_implementation_);
-
- if (traits_helper::less_than(now, expiry_time))
+ // Check if we are past the expiry time.
+ if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
- this_->timer_state_ = timer_is_pending;
- this_->timer_service_->async_wait(this_->timer_implementation_, *this);
+ ec_ = boost::asio::error::timed_out;
+ return;
}
- else
- {
- this_->timer_state_ = timer_has_expired;
- boost::system::error_code ec;
- this_->basic_socket<Protocol, StreamSocketService>::close(ec);
- }
- }
- };
- void construct_timer()
- {
- if (timer_service_ == 0)
- {
- TimerService& timer_service = use_service<TimerService>(
- detail::socket_streambuf_base::io_service_);
- timer_service.construct(timer_implementation_);
- timer_service_ = &timer_service;
+ // Close and reopen the socket.
+ typename Protocol::endpoint ep(*i);
+ socket().close(ec_);
+ socket().open(ep.protocol(), ec_);
+ if (ec_)
+ continue;
+
+ // Try to complete the operation without blocking.
+ if (!socket().native_non_blocking())
+ socket().native_non_blocking(true, ec_);
+ detail::socket_ops::connect(socket().native_handle(),
+ ep.data(), ep.size(), ec_);
+
+ // Check if operation succeeded.
+ if (!ec_)
+ return;
+
+ // Operation failed.
+ if (ec_ != boost::asio::error::in_progress
+ && ec_ != boost::asio::error::would_block)
+ continue;
+
+ // Wait for socket to become ready.
+ if (detail::socket_ops::poll_connect(
+ socket().native_handle(), timeout(), ec_) < 0)
+ continue;
+
+ // Get the error code from the connect operation.
+ int connect_error = 0;
+ size_t connect_error_len = sizeof(connect_error);
+ if (detail::socket_ops::getsockopt(socket().native_handle(), 0,
+ SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_)
+ == detail::socket_error_retval)
+ return;
+
+ // Check the result of the connect operation.
+ ec_ = boost::system::error_code(connect_error,
+ boost::asio::error::get_system_category());
+ if (!ec_)
+ return;
}
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
}
- void destroy_timer()
+ // Helper function to get the maximum expiry time.
+ static time_point max_expiry_time()
{
- if (timer_service_)
- timer_service_->destroy(timer_implementation_);
- }
-
- void start_timer()
- {
- if (timer_state_ != timer_is_pending)
- {
- timer_handler handler = { this };
- handler(boost::system::error_code());
- }
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+ return boost::posix_time::pos_infin;
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+ return (time_point::max)();
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
}
enum { putback_max = 8 };
- enum { buffer_size = 512 };
- boost::asio::detail::array<char, buffer_size> get_buffer_;
- boost::asio::detail::array<char, buffer_size> put_buffer_;
- bool unbuffered_;
boost::system::error_code ec_;
- std::size_t bytes_transferred_;
- TimerService* timer_service_;
- typename TimerService::implementation_type timer_implementation_;
- enum state { no_timer, timer_is_pending, timer_has_expired } timer_state_;
+ time_point expiry_time_;
};
} // namespace asio
@@ -560,6 +684,10 @@ private:
#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T1
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# undef BOOST_ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
diff --git a/boost/asio/basic_stream_socket.hpp b/boost/asio/basic_stream_socket.hpp
index 5b959d7db8..709e214a37 100644
--- a/boost/asio/basic_stream_socket.hpp
+++ b/boost/asio/basic_stream_socket.hpp
@@ -22,7 +22,10 @@
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/stream_socket_service.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
@@ -41,18 +44,19 @@ namespace asio {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
-template <typename Protocol,
- typename StreamSocketService = stream_socket_service<Protocol> >
+template <typename Protocol
+ BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
class basic_stream_socket
- : public basic_socket<Protocol, StreamSocketService>
+ : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
{
public:
- /// (Deprecated: Use native_handle_type.) The native representation of a
- /// socket.
- typedef typename StreamSocketService::native_handle_type native_type;
-
/// The native representation of a socket.
- typedef typename StreamSocketService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket<
+ Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
/// The protocol type.
typedef Protocol protocol_type;
@@ -66,11 +70,11 @@ public:
* needs to be opened and then connected or accepted before data can be sent
* or received on it.
*
- * @param io_service The io_service object that the stream socket will use to
+ * @param io_context The io_context object that the stream socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
- explicit basic_stream_socket(boost::asio::io_service& io_service)
- : basic_socket<Protocol, StreamSocketService>(io_service)
+ explicit basic_stream_socket(boost::asio::io_context& io_context)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
{
}
@@ -79,16 +83,16 @@ public:
* 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.
*
- * @param io_service The io_service object that the stream socket will use to
+ * @param io_context The io_context object that the stream socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_service& io_service,
+ basic_stream_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
- : basic_socket<Protocol, StreamSocketService>(io_service, protocol)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
{
}
@@ -99,7 +103,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_service The io_service object that the stream socket will use to
+ * @param io_context The io_context object that the stream socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the stream
@@ -107,9 +111,9 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_service& io_service,
+ basic_stream_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
- : basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
{
}
@@ -118,7 +122,7 @@ public:
* This constructor creates a stream socket object to hold an existing native
* socket.
*
- * @param io_service The io_service object that the stream socket will use to
+ * @param io_context The io_context object that the stream socket will use to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
@@ -127,10 +131,10 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_service& io_service,
+ basic_stream_socket(boost::asio::io_context& io_context,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol, StreamSocketService>(
- io_service, protocol, native_socket)
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+ io_context, protocol, native_socket)
{
}
@@ -143,11 +147,10 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_service&) constructor.
+ * constructed using the @c basic_stream_socket(io_context&) constructor.
*/
basic_stream_socket(basic_stream_socket&& other)
- : basic_socket<Protocol, StreamSocketService>(
- BOOST_ASIO_MOVE_CAST(basic_stream_socket)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -159,12 +162,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_service&) constructor.
+ * constructed using the @c basic_stream_socket(io_context&) constructor.
*/
basic_stream_socket& operator=(basic_stream_socket&& other)
{
- basic_socket<Protocol, StreamSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_stream_socket)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
@@ -177,15 +179,13 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_service&) constructor.
+ * constructed using the @c basic_stream_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename StreamSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_stream_socket(
- basic_stream_socket<Protocol1, StreamSocketService1>&& other,
+ basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol, StreamSocketService>(
- BOOST_ASIO_MOVE_CAST2(basic_stream_socket<
- Protocol1, StreamSocketService1>)(other))
+ : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
{
}
@@ -197,20 +197,27 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_service&) constructor.
+ * constructed using the @c basic_stream_socket(io_context&) constructor.
*/
- template <typename Protocol1, typename StreamSocketService1>
+ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_stream_socket>::type& operator=(
- basic_stream_socket<Protocol1, StreamSocketService1>&& other)
+ basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
{
- basic_socket<Protocol, StreamSocketService>::operator=(
- BOOST_ASIO_MOVE_CAST2(basic_stream_socket<
- Protocol1, StreamSocketService1>)(other));
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_stream_socket()
+ {
+ }
+
/// Send some data on the socket.
/**
* This function is used to send data on the stream socket. The function
@@ -330,7 +337,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -355,9 +362,20 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, 0,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(
+ this->get_implementation(), buffers, 0,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous send.
@@ -382,7 +400,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -408,9 +426,20 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(
+ this->get_implementation(), buffers, flags,
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Receive some data on the socket.
@@ -538,7 +567,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -565,8 +594,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Start an asynchronous receive.
@@ -591,7 +630,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -619,8 +658,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, flags, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Write some data to the socket.
@@ -703,7 +752,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -728,8 +777,18 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_send(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
/// Read some data from the socket.
@@ -815,7 +874,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -841,8 +900,18 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->get_service().async_receive(this->get_implementation(),
+ buffers, 0, init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
};
diff --git a/boost/asio/basic_streambuf.hpp b/boost/asio/basic_streambuf.hpp
index 1392596dc5..d8bfecd6b6 100644
--- a/boost/asio/basic_streambuf.hpp
+++ b/boost/asio/basic_streambuf.hpp
@@ -120,8 +120,8 @@ public:
/// The type used to represent the output sequence as a list of buffers.
typedef implementation_defined mutable_buffers_type;
#else
- typedef boost::asio::const_buffers_1 const_buffers_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
+ typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+ typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
#endif
/// Construct a basic_streambuf object.
@@ -152,11 +152,11 @@ public:
* while (i != bufs.end())
* {
* const_buffer buf(*i++);
- * s += buffer_size(buf);
+ * s += buf.size();
* }
* @endcode
*/
- std::size_t size() const
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
{
return pptr() - gptr();
}
@@ -166,11 +166,21 @@ public:
* @returns The allowed maximum of the sum of the sizes of the input sequence
* and output sequence.
*/
- std::size_t max_size() const
+ std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
return max_size_;
}
+ /// Get the current capacity of the basic_streambuf.
+ /**
+ * @returns The current total capacity of the streambuf, i.e. for both the
+ * input sequence and output sequence.
+ */
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+ {
+ return buffer_.capacity();
+ }
+
/// Get a list of buffers that represents the input sequence.
/**
* @returns An object of type @c const_buffers_type that satisfies
@@ -180,7 +190,7 @@ public:
* @note The returned object is invalidated by any @c basic_streambuf member
* function that modifies the input sequence or output sequence.
*/
- const_buffers_type data() const
+ const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{
return boost::asio::buffer(boost::asio::const_buffer(gptr(),
(pptr() - gptr()) * sizeof(char_type)));
@@ -223,8 +233,7 @@ public:
*/
void commit(std::size_t n)
{
- if (pptr() + n > epptr())
- n = epptr() - pptr();
+ n = std::min<std::size_t>(n, epptr() - pptr());
pbump(static_cast<int>(n));
setg(eback(), gptr(), pptr());
}
@@ -351,15 +360,89 @@ private:
}
};
-// Helper function to get the preferred size for reading data. Used for any
-// user-provided specialisations of basic_streambuf.
+/// Adapts basic_streambuf to the dynamic buffer sequence type requirements.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Allocator = std::allocator<char> >
+#else
template <typename Allocator>
-inline std::size_t read_size_helper(
- basic_streambuf<Allocator>& sb, std::size_t max_size)
+#endif
+class basic_streambuf_ref
{
- return std::min<std::size_t>(512,
- std::min<std::size_t>(max_size, sb.max_size() - sb.size()));
-}
+public:
+ /// The type used to represent the input sequence as a list of buffers.
+ typedef typename basic_streambuf<Allocator>::const_buffers_type
+ const_buffers_type;
+
+ /// The type used to represent the output sequence as a list of buffers.
+ typedef typename basic_streambuf<Allocator>::mutable_buffers_type
+ mutable_buffers_type;
+
+ /// Construct a basic_streambuf_ref for the given basic_streambuf object.
+ explicit basic_streambuf_ref(basic_streambuf<Allocator>& sb)
+ : sb_(sb)
+ {
+ }
+
+ /// Copy construct a basic_streambuf_ref.
+ basic_streambuf_ref(const basic_streambuf_ref& other) BOOST_ASIO_NOEXCEPT
+ : sb_(other.sb_)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move construct a basic_streambuf_ref.
+ basic_streambuf_ref(basic_streambuf_ref&& other) BOOST_ASIO_NOEXCEPT
+ : sb_(other.sb_)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Get the size of the input sequence.
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
+ {
+ return sb_.size();
+ }
+
+ /// Get the maximum size of the dynamic buffer.
+ std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+ {
+ return sb_.max_size();
+ }
+
+ /// Get the current capacity of the dynamic buffer.
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+ {
+ return sb_.capacity();
+ }
+
+ /// Get a list of buffers that represents the input sequence.
+ const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+ {
+ return sb_.data();
+ }
+
+ /// Get a list of buffers that represents the output sequence, with the given
+ /// size.
+ mutable_buffers_type prepare(std::size_t n)
+ {
+ return sb_.prepare(n);
+ }
+
+ /// Move bytes from the output sequence to the input sequence.
+ void commit(std::size_t n)
+ {
+ return sb_.commit(n);
+ }
+
+ /// Remove characters from the input sequence.
+ void consume(std::size_t n)
+ {
+ return sb_.consume(n);
+ }
+
+private:
+ basic_streambuf<Allocator>& sb_;
+};
} // namespace asio
} // namespace boost
diff --git a/boost/asio/basic_streambuf_fwd.hpp b/boost/asio/basic_streambuf_fwd.hpp
index f3e006bf11..b34e3459bb 100644
--- a/boost/asio/basic_streambuf_fwd.hpp
+++ b/boost/asio/basic_streambuf_fwd.hpp
@@ -27,6 +27,9 @@ namespace asio {
template <typename Allocator = std::allocator<char> >
class basic_streambuf;
+template <typename Allocator = std::allocator<char> >
+class basic_streambuf_ref;
+
} // namespace asio
} // namespace boost
diff --git a/boost/asio/basic_waitable_timer.hpp b/boost/asio/basic_waitable_timer.hpp
index e4aeb0b7d8..3657d8b429 100644
--- a/boost/asio/basic_waitable_timer.hpp
+++ b/boost/asio/basic_waitable_timer.hpp
@@ -22,13 +22,37 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/wait_traits.hpp>
-#include <boost/asio/waitable_timer_service.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/waitable_timer_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/chrono_time_traits.hpp>
+# include <boost/asio/detail/deadline_timer_service.hpp>
+# define BOOST_ASIO_SVC_T \
+ detail::deadline_timer_service< \
+ detail::chrono_time_traits<Clock, WaitTraits> >
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
+#define BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Clock,
+ typename WaitTraits = boost::asio::wait_traits<Clock>
+ BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
+class basic_waitable_timer;
+
+#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
+
/// Provides waitable timer functionality.
/**
* The basic_waitable_timer class template provides the ability to perform a
@@ -52,10 +76,10 @@ namespace asio {
* Performing a blocking wait (C++11):
* @code
* // Construct a timer without setting an expiry time.
- * boost::asio::steady_timer timer(io_service);
+ * boost::asio::steady_timer timer(io_context);
*
* // Set an expiry time relative to now.
- * timer.expires_from_now(std::chrono::seconds(5));
+ * timer.expires_after(std::chrono::seconds(5));
*
* // Wait for the timer to expire.
* timer.wait();
@@ -75,7 +99,7 @@ namespace asio {
* ...
*
* // Construct a timer with an absolute expiry time.
- * boost::asio::steady_timer timer(io_service,
+ * boost::asio::steady_timer timer(io_context,
* std::chrono::steady_clock::now() + std::chrono::seconds(60));
*
* // Start an asynchronous wait.
@@ -92,7 +116,7 @@ namespace asio {
* @code
* void on_some_event()
* {
- * if (my_timer.expires_from_now(seconds(5)) > 0)
+ * if (my_timer.expires_after(seconds(5)) > 0)
* {
* // We managed to cancel the timer. Start new asynchronous wait.
* my_timer.async_wait(on_timeout);
@@ -112,7 +136,7 @@ namespace asio {
* }
* @endcode
*
- * @li The boost::asio::basic_waitable_timer::expires_from_now() function
+ * @li The boost::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
@@ -121,13 +145,14 @@ namespace asio {
* @li If a wait handler is cancelled, the boost::system::error_code passed to
* it contains the value boost::asio::error::operation_aborted.
*/
-template <typename Clock,
- typename WaitTraits = boost::asio::wait_traits<Clock>,
- typename WaitableTimerService = waitable_timer_service<Clock, WaitTraits> >
+template <typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM>
class basic_waitable_timer
- : public basic_io_object<WaitableTimerService>
+ : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
+ /// The type of the executor associated with the object.
+ typedef io_context::executor_type executor_type;
+
/// The clock type.
typedef Clock clock_type;
@@ -143,14 +168,14 @@ public:
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
- * expires_at() or expires_from_now() functions must be called to set an
- * expiry time before the timer can be waited on.
+ * expires_at() or expires_after() functions must be called to set an expiry
+ * time before the timer can be waited on.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*/
- explicit basic_waitable_timer(boost::asio::io_service& io_service)
- : basic_io_object<WaitableTimerService>(io_service)
+ explicit basic_waitable_timer(boost::asio::io_context& io_context)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
}
@@ -158,18 +183,18 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
- basic_waitable_timer(boost::asio::io_service& io_service,
+ basic_waitable_timer(boost::asio::io_context& io_context,
const time_point& expiry_time)
- : basic_io_object<WaitableTimerService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
- this->service.expires_at(this->implementation, expiry_time, ec);
+ this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
@@ -177,21 +202,105 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_service The io_service object that the timer will use to dispatch
+ * @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
- basic_waitable_timer(boost::asio::io_service& io_service,
+ basic_waitable_timer(boost::asio::io_context& io_context,
const duration& expiry_time)
- : basic_io_object<WaitableTimerService>(io_service)
+ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{
boost::system::error_code ec;
- this->service.expires_from_now(this->implementation, expiry_time, ec);
- boost::asio::detail::throw_error(ec, "expires_from_now");
+ this->get_service().expires_after(
+ this->get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_after");
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_waitable_timer from another.
+ /**
+ * This constructor moves a timer from one object to another.
+ *
+ * @param other The other basic_waitable_timer object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_waitable_timer(io_context&) constructor.
+ */
+ basic_waitable_timer(basic_waitable_timer&& other)
+ : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_waitable_timer from another.
+ /**
+ * This assignment operator moves a timer from one object to another. Cancels
+ * any outstanding asynchronous operations associated with the target object.
+ *
+ * @param other The other basic_waitable_timer object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_waitable_timer(io_context&) constructor.
+ */
+ basic_waitable_timer& operator=(basic_waitable_timer&& other)
+ {
+ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destroys the timer.
+ /**
+ * This function destroys the timer, cancelling any outstanding asynchronous
+ * wait operations associated with the timer as if by calling @c cancel.
+ */
+ ~basic_waitable_timer()
+ {
+ }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_context()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
}
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ /**
+ * This function may be used to obtain the io_context object that the I/O
+ * object uses to dispatch handlers for asynchronous operations.
+ *
+ * @return A reference to the io_context object that the I/O object will use
+ * to dispatch handlers. Ownership is not transferred to the caller.
+ */
+ boost::asio::io_context& get_io_service()
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
@@ -217,12 +326,14 @@ public:
std::size_t cancel()
{
boost::system::error_code ec;
- std::size_t s = this->service.cancel(this->implementation, ec);
+ std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
return s;
}
- /// Cancel any asynchronous operations that are waiting on the timer.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous
+ /// operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
* operations against the timer. The handler for each cancelled operation will
@@ -246,8 +357,9 @@ public:
*/
std::size_t cancel(boost::system::error_code& ec)
{
- return this->service.cancel(this->implementation, ec);
+ return this->get_service().cancel(this->get_implementation(), ec);
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Cancels one asynchronous operation that is waiting on the timer.
/**
@@ -276,12 +388,15 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
- std::size_t s = this->service.cancel_one(this->implementation, ec);
+ std::size_t s = this->get_service().cancel_one(
+ this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
- /// Cancels one asynchronous operation that is waiting on the timer.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous
+ /// operation that is waiting on the timer.
/**
* This function forces the completion of one pending asynchronous wait
* operation against the timer. Handlers are cancelled in FIFO order. The
@@ -307,17 +422,29 @@ public:
*/
std::size_t cancel_one(boost::system::error_code& ec)
{
- return this->service.cancel_one(this->implementation, ec);
+ return this->get_service().cancel_one(this->get_implementation(), ec);
}
- /// Get the timer's expiry time as an absolute time.
+ /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
+ /// time.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
time_point expires_at() const
{
- return this->service.expires_at(this->implementation);
+ return this->get_service().expires_at(this->get_implementation());
+ }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ /// Get the timer's expiry time as an absolute time.
+ /**
+ * This function may be used to obtain the timer's current expiry time.
+ * Whether the timer has expired or not does not affect this value.
+ */
+ time_point expiry() const
+ {
+ return this->get_service().expiry(this->get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -345,13 +472,15 @@ public:
std::size_t expires_at(const time_point& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->service.expires_at(
- this->implementation, expiry_time, ec);
+ std::size_t s = this->get_service().expires_at(
+ this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
- /// Set the timer's expiry time as an absolute time.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as
+ /// an absolute time.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
@@ -376,20 +505,55 @@ public:
std::size_t expires_at(const time_point& expiry_time,
boost::system::error_code& ec)
{
- return this->service.expires_at(this->implementation, expiry_time, ec);
+ return this->get_service().expires_at(
+ this->get_implementation(), expiry_time, ec);
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
- /// Get the timer's expiry time relative to now.
+ /// Set the timer's expiry time relative to now.
+ /**
+ * This function sets the expiry time. Any pending asynchronous wait
+ * operations will be cancelled. The handler for each cancelled operation will
+ * be invoked with the boost::asio::error::operation_aborted error code.
+ *
+ * @param expiry_time The expiry time to be used for the timer.
+ *
+ * @return The number of asynchronous operations that were cancelled.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note If the timer has already expired when expires_after() is called,
+ * then the handlers for asynchronous wait operations will:
+ *
+ * @li have already been invoked; or
+ *
+ * @li have been queued for invocation in the near future.
+ *
+ * These handlers can no longer be cancelled, and therefore are passed an
+ * error code that indicates the successful completion of the wait operation.
+ */
+ std::size_t expires_after(const duration& expiry_time)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->get_service().expires_after(
+ this->get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_after");
+ return s;
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
duration expires_from_now() const
{
- return this->service.expires_from_now(this->implementation);
+ return this->get_service().expires_from_now(this->get_implementation());
}
- /// Set the timer's expiry time relative to now.
+ /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+ /// to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
@@ -414,13 +578,14 @@ public:
std::size_t expires_from_now(const duration& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->service.expires_from_now(
- this->implementation, expiry_time, ec);
+ std::size_t s = this->get_service().expires_from_now(
+ this->get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
- /// Set the timer's expiry time relative to now.
+ /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+ /// to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
@@ -445,9 +610,10 @@ public:
std::size_t expires_from_now(const duration& expiry_time,
boost::system::error_code& ec)
{
- return this->service.expires_from_now(
- this->implementation, expiry_time, ec);
+ return this->get_service().expires_from_now(
+ this->get_implementation(), expiry_time, ec);
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Perform a blocking wait on the timer.
/**
@@ -459,7 +625,7 @@ public:
void wait()
{
boost::system::error_code ec;
- this->service.wait(this->implementation, ec);
+ this->get_service().wait(this->get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -472,7 +638,7 @@ public:
*/
void wait(boost::system::error_code& ec)
{
- this->service.wait(this->implementation, ec);
+ this->get_service().wait(this->get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -497,7 +663,7 @@ public:
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
@@ -508,9 +674,25 @@ public:
// not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
- return this->service.async_wait(this->implementation,
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ this->get_service().async_wait(this->get_implementation(),
+ init.completion_handler);
+
+ return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
}
+
+private:
+ // Disallow copying and assignment.
+ basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
+ basic_waitable_timer& operator=(
+ const basic_waitable_timer&) BOOST_ASIO_DELETED;
};
} // namespace asio
@@ -518,4 +700,8 @@ public:
#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
diff --git a/boost/asio/bind_executor.hpp b/boost/asio/bind_executor.hpp
new file mode 100644
index 0000000000..f6db65fc91
--- /dev/null
+++ b/boost/asio/bind_executor.hpp
@@ -0,0 +1,613 @@
+//
+// bind_executor.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BIND_EXECUTOR_HPP
+#define BOOST_ASIO_BIND_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/detail/variadic_templates.hpp>
+#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/associated_allocator.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/is_executor.hpp>
+#include <boost/asio/uses_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+struct executor_binder_check
+{
+ typedef void type;
+};
+
+// Helper to automatically define nested typedef result_type.
+
+template <typename T, typename = void>
+struct executor_binder_result_type
+{
+protected:
+ typedef void result_type_or_void;
+};
+
+template <typename T>
+struct executor_binder_result_type<T,
+ typename executor_binder_check<typename T::result_type>::type>
+{
+ typedef typename T::result_type result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R>
+struct executor_binder_result_type<R(*)()>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R>
+struct executor_binder_result_type<R(&)()>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1>
+struct executor_binder_result_type<R(*)(A1)>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1>
+struct executor_binder_result_type<R(&)(A1)>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_result_type<R(*)(A1, A2)>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_result_type<R(&)(A1, A2)>
+{
+ typedef R result_type;
+protected:
+ typedef result_type result_type_or_void;
+};
+
+// Helper to automatically define nested typedef argument_type.
+
+template <typename T, typename = void>
+struct executor_binder_argument_type {};
+
+template <typename T>
+struct executor_binder_argument_type<T,
+ typename executor_binder_check<typename T::argument_type>::type>
+{
+ typedef typename T::argument_type argument_type;
+};
+
+template <typename R, typename A1>
+struct executor_binder_argument_type<R(*)(A1)>
+{
+ typedef A1 argument_type;
+};
+
+template <typename R, typename A1>
+struct executor_binder_argument_type<R(&)(A1)>
+{
+ typedef A1 argument_type;
+};
+
+// Helper to automatically define nested typedefs first_argument_type and
+// second_argument_type.
+
+template <typename T, typename = void>
+struct executor_binder_argument_types {};
+
+template <typename T>
+struct executor_binder_argument_types<T,
+ typename executor_binder_check<typename T::first_argument_type>::type>
+{
+ typedef typename T::first_argument_type first_argument_type;
+ typedef typename T::second_argument_type second_argument_type;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_argument_type<R(*)(A1, A2)>
+{
+ typedef A1 first_argument_type;
+ typedef A2 second_argument_type;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_argument_type<R(&)(A1, A2)>
+{
+ typedef A1 first_argument_type;
+ typedef A2 second_argument_type;
+};
+
+// Helper to:
+// - Apply the empty base optimisation to the executor.
+// - Perform uses_executor construction of the target type, if required.
+
+template <typename T, typename Executor, bool UsesExecutor>
+class executor_binder_base;
+
+template <typename T, typename Executor>
+class executor_binder_base<T, Executor, true>
+ : protected Executor
+{
+protected:
+ template <typename E, typename U>
+ executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
+ : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
+ target_(executor_arg_t(), executor_, BOOST_ASIO_MOVE_CAST(U)(u))
+ {
+ }
+
+ Executor executor_;
+ T target_;
+};
+
+template <typename T, typename Executor>
+class executor_binder_base<T, Executor, false>
+{
+protected:
+ template <typename E, typename U>
+ executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
+ : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
+ target_(BOOST_ASIO_MOVE_CAST(U)(u))
+ {
+ }
+
+ Executor executor_;
+ T target_;
+};
+
+// Helper to enable SFINAE on zero-argument operator() below.
+
+template <typename T, typename = void>
+struct executor_binder_result_of0
+{
+ typedef void type;
+};
+
+template <typename T>
+struct executor_binder_result_of0<T,
+ typename executor_binder_check<typename result_of<T()>::type>::type>
+{
+ typedef typename result_of<T()>::type type;
+};
+
+} // namespace detail
+
+/// A call wrapper type to bind an executor of type @c Executor to an object of
+/// type @c T.
+template <typename T, typename Executor>
+class executor_binder
+#if !defined(GENERATING_DOCUMENTATION)
+ : public detail::executor_binder_result_type<T>,
+ public detail::executor_binder_argument_type<T>,
+ public detail::executor_binder_argument_types<T>,
+ private detail::executor_binder_base<
+ T, Executor, uses_executor<T, Executor>::value>
+#endif // !defined(GENERATING_DOCUMENTATION)
+{
+public:
+ /// The type of the target object.
+ typedef T target_type;
+
+ /// The type of the associated executor.
+ typedef Executor executor_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+ /// The return type if a function.
+ /**
+ * The type of @c result_type is based on the type @c T of the wrapper's
+ * target object:
+ *
+ * @li if @c T is a pointer to function type, @c result_type is a synonym for
+ * the return type of @c T;
+ *
+ * @li if @c T is a class type with a member type @c result_type, then @c
+ * result_type is a synonym for @c T::result_type;
+ *
+ * @li otherwise @c result_type is not defined.
+ */
+ typedef see_below result_type;
+
+ /// The type of the function's argument.
+ /**
+ * The type of @c argument_type is based on the type @c T of the wrapper's
+ * target object:
+ *
+ * @li if @c T is a pointer to a function type accepting a single argument,
+ * @c argument_type is a synonym for the return type of @c T;
+ *
+ * @li if @c T is a class type with a member type @c argument_type, then @c
+ * argument_type is a synonym for @c T::argument_type;
+ *
+ * @li otherwise @c argument_type is not defined.
+ */
+ typedef see_below argument_type;
+
+ /// The type of the function's first argument.
+ /**
+ * The type of @c first_argument_type is based on the type @c T of the
+ * wrapper's target object:
+ *
+ * @li if @c T is a pointer to a function type accepting two arguments, @c
+ * first_argument_type is a synonym for the return type of @c T;
+ *
+ * @li if @c T is a class type with a member type @c first_argument_type,
+ * then @c first_argument_type is a synonym for @c T::first_argument_type;
+ *
+ * @li otherwise @c first_argument_type is not defined.
+ */
+ typedef see_below first_argument_type;
+
+ /// The type of the function's second argument.
+ /**
+ * The type of @c second_argument_type is based on the type @c T of the
+ * wrapper's target object:
+ *
+ * @li if @c T is a pointer to a function type accepting two arguments, @c
+ * second_argument_type is a synonym for the return type of @c T;
+ *
+ * @li if @c T is a class type with a member type @c first_argument_type,
+ * then @c second_argument_type is a synonym for @c T::second_argument_type;
+ *
+ * @li otherwise @c second_argument_type is not defined.
+ */
+ typedef see_below second_argument_type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+ /// Construct an executor wrapper for the specified object.
+ /**
+ * This constructor is only valid if the type @c T is constructible from type
+ * @c U.
+ */
+ template <typename U>
+ executor_binder(executor_arg_t, const executor_type& e,
+ BOOST_ASIO_MOVE_ARG(U) u)
+ : base_type(e, BOOST_ASIO_MOVE_CAST(U)(u))
+ {
+ }
+
+ /// Copy constructor.
+ executor_binder(const executor_binder& other)
+ : base_type(other.get_executor(), other.get())
+ {
+ }
+
+ /// Construct a copy, but specify a different executor.
+ executor_binder(executor_arg_t, const executor_type& e,
+ const executor_binder& other)
+ : base_type(e, other.get())
+ {
+ }
+
+ /// Construct a copy of a different executor wrapper type.
+ /**
+ * This constructor is only valid if the @c Executor type is constructible
+ * from type @c OtherExecutor, and the type @c T is constructible from type
+ * @c U.
+ */
+ template <typename U, typename OtherExecutor>
+ executor_binder(const executor_binder<U, OtherExecutor>& other)
+ : base_type(other.get_executor(), other.get())
+ {
+ }
+
+ /// Construct a copy of a different executor wrapper type, but specify a
+ /// different executor.
+ /**
+ * This constructor is only valid if the type @c T is constructible from type
+ * @c U.
+ */
+ template <typename U, typename OtherExecutor>
+ executor_binder(executor_arg_t, const executor_type& e,
+ const executor_binder<U, OtherExecutor>& other)
+ : base_type(e, other.get())
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Move constructor.
+ executor_binder(executor_binder&& other)
+ : base_type(BOOST_ASIO_MOVE_CAST(executor_type)(other.get_executor()),
+ BOOST_ASIO_MOVE_CAST(T)(other.get()))
+ {
+ }
+
+ /// Move construct the target object, but specify a different executor.
+ executor_binder(executor_arg_t, const executor_type& e,
+ executor_binder&& other)
+ : base_type(e, BOOST_ASIO_MOVE_CAST(T)(other.get()))
+ {
+ }
+
+ /// Move construct from a different executor wrapper type.
+ template <typename U, typename OtherExecutor>
+ executor_binder(executor_binder<U, OtherExecutor>&& other)
+ : base_type(BOOST_ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),
+ BOOST_ASIO_MOVE_CAST(U)(other.get()))
+ {
+ }
+
+ /// Move construct from a different executor wrapper type, but specify a
+ /// different executor.
+ template <typename U, typename OtherExecutor>
+ executor_binder(executor_arg_t, const executor_type& e,
+ executor_binder<U, OtherExecutor>&& other)
+ : base_type(e, BOOST_ASIO_MOVE_CAST(U)(other.get()))
+ {
+ }
+
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destructor.
+ ~executor_binder()
+ {
+ }
+
+ /// Obtain a reference to the target object.
+ target_type& get() BOOST_ASIO_NOEXCEPT
+ {
+ return this->target_;
+ }
+
+ /// Obtain a reference to the target object.
+ const target_type& get() const BOOST_ASIO_NOEXCEPT
+ {
+ return this->target_;
+ }
+
+ /// Obtain the associated executor.
+ executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+ {
+ return this->executor_;
+ }
+
+#if defined(GENERATING_DOCUMENTATION)
+
+ template <typename... Args> auto operator()(Args&& ...);
+ template <typename... Args> auto operator()(Args&& ...) const;
+
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ /// Forwarding function call operator.
+ template <typename... Args>
+ typename result_of<T(Args...)>::type operator()(
+ BOOST_ASIO_MOVE_ARG(Args)... args)
+ {
+ return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
+
+ /// Forwarding function call operator.
+ template <typename... Args>
+ typename result_of<T(Args...)>::type operator()(
+ BOOST_ASIO_MOVE_ARG(Args)... args) const
+ {
+ return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
+
+#elif defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+ typename detail::executor_binder_result_of0<T>::type operator()()
+ {
+ return this->target_();
+ }
+
+ typename detail::executor_binder_result_of0<T>::type operator()() const
+ {
+ return this->target_();
+ }
+
+#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
+ template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ \
+ template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
+ { \
+ return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
+#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
+
+#else // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+ typedef typename detail::executor_binder_result_type<T>::result_type_or_void
+ result_type_or_void;
+
+ result_type_or_void operator()()
+ {
+ return this->target_();
+ }
+
+ result_type_or_void operator()() const
+ {
+ return this->target_();
+ }
+
+#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
+ template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ result_type_or_void operator()( \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ \
+ template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ result_type_or_void operator()( \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
+ { \
+ return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
+#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
+
+#endif // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+private:
+ typedef detail::executor_binder_base<T, Executor,
+ uses_executor<T, Executor>::value> base_type;
+};
+
+/// Associate an object of type @c T with an executor of type @c Executor.
+template <typename Executor, typename T>
+inline executor_binder<typename decay<T>::type, Executor>
+bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,
+ typename enable_if<is_executor<Executor>::value>::type* = 0)
+{
+ return executor_binder<typename decay<T>::type, Executor>(
+ executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));
+}
+
+/// Associate an object of type @c T with an execution context's executor.
+template <typename ExecutionContext, typename T>
+inline executor_binder<typename decay<T>::type,
+ typename ExecutionContext::executor_type>
+bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,
+ typename enable_if<is_convertible<
+ ExecutionContext&, execution_context&>::value>::type* = 0)
+{
+ return executor_binder<typename decay<T>::type,
+ typename ExecutionContext::executor_type>(
+ executor_arg_t(), ctx.get_executor(), BOOST_ASIO_MOVE_CAST(T)(t));
+}
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename T, typename Executor>
+struct uses_executor<executor_binder<T, Executor>, Executor>
+ : true_type {};
+
+template <typename T, typename Executor, typename Signature>
+class async_result<executor_binder<T, Executor>, Signature>
+{
+public:
+ typedef executor_binder<
+ typename async_result<T, Signature>::completion_handler_type, Executor>
+ completion_handler_type;
+
+ typedef typename async_result<T, Signature>::return_type return_type;
+
+ explicit async_result(executor_binder<T, Executor>& b)
+ : target_(b.get())
+ {
+ }
+
+ return_type get()
+ {
+ return target_.get();
+ }
+
+private:
+ async_result(const async_result&) BOOST_ASIO_DELETED;
+ async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
+
+ async_result<T, Signature> target_;
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename T, typename Executor, typename Signature>
+struct handler_type<executor_binder<T, Executor>, Signature>
+{
+ typedef executor_binder<
+ typename handler_type<T, Signature>::type, Executor> type;
+};
+
+template <typename T, typename Executor>
+class async_result<executor_binder<T, Executor> >
+{
+public:
+ typedef typename async_result<T>::type type;
+
+ explicit async_result(executor_binder<T, Executor>& b)
+ : target_(b.get())
+ {
+ }
+
+ type get()
+ {
+ return target_.get();
+ }
+
+private:
+ async_result<T> target_;
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename T, typename Executor, typename Allocator>
+struct associated_allocator<executor_binder<T, Executor>, Allocator>
+{
+ typedef typename associated_allocator<T, Allocator>::type type;
+
+ static type get(const executor_binder<T, Executor>& b,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<T, Allocator>::get(b.get(), a);
+ }
+};
+
+template <typename T, typename Executor, typename Executor1>
+struct associated_executor<executor_binder<T, Executor>, Executor1>
+{
+ typedef Executor type;
+
+ static type get(const executor_binder<T, Executor>& b,
+ const Executor1& = Executor1()) BOOST_ASIO_NOEXCEPT
+ {
+ return b.get_executor();
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BIND_EXECUTOR_HPP
diff --git a/boost/asio/buffer.hpp b/boost/asio/buffer.hpp
index 700654d21d..66d638ec51 100644
--- a/boost/asio/buffer.hpp
+++ b/boost/asio/buffer.hpp
@@ -18,17 +18,23 @@
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <cstring>
+#include <limits>
+#include <stdexcept>
#include <string>
#include <vector>
#include <boost/asio/detail/array_fwd.hpp>
+#include <boost/asio/detail/is_buffer_sequence.hpp>
+#include <boost/asio/detail/string_view.hpp>
+#include <boost/asio/detail/throw_exception.hpp>
+#include <boost/asio/detail/type_traits.hpp>
-#if defined(BOOST_ASIO_MSVC)
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
# if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
# define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
# endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
# endif // defined(_HAS_ITERATOR_DEBUGGING)
-#endif // defined(BOOST_ASIO_MSVC)
+#endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
#if defined(__GNUC__)
# if defined(_GLIBCXX_DEBUG)
@@ -39,7 +45,7 @@
#endif // defined(__GNUC__)
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-# include <boost/asio/detail/function.hpp>
+# include <boost/asio/detail/functional.hpp>
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
#if defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
@@ -63,13 +69,6 @@ namespace asio {
class mutable_buffer;
class const_buffer;
-namespace detail {
-void* buffer_cast_helper(const mutable_buffer&);
-const void* buffer_cast_helper(const const_buffer&);
-std::size_t buffer_size_helper(const mutable_buffer&);
-std::size_t buffer_size_helper(const const_buffer&);
-} // namespace detail
-
/// Holds a buffer that can be modified.
/**
* The mutable_buffer class provides a safe representation of a buffer that can
@@ -78,29 +77,29 @@ std::size_t buffer_size_helper(const const_buffer&);
*
* @par Accessing Buffer Contents
*
- * The contents of a buffer may be accessed using the @ref buffer_size
- * and @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
*
* @code boost::asio::mutable_buffer b1 = ...;
- * std::size_t s1 = boost::asio::buffer_size(b1);
- * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
* @endcode
*
- * The boost::asio::buffer_cast function permits violations of type safety, so
- * uses of it in application code should be carefully considered.
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
*/
class mutable_buffer
{
public:
/// Construct an empty buffer.
- mutable_buffer()
+ mutable_buffer() BOOST_ASIO_NOEXCEPT
: data_(0),
size_(0)
{
}
/// Construct a buffer to represent a given memory range.
- mutable_buffer(void* data, std::size_t size)
+ mutable_buffer(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
: data_(data),
size_(size)
{
@@ -121,12 +120,32 @@ public:
}
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
-private:
- friend void* boost::asio::detail::buffer_cast_helper(
- const mutable_buffer& b);
- friend std::size_t boost::asio::detail::buffer_size_helper(
- const mutable_buffer& b);
+ /// Get a pointer to the beginning of the memory range.
+ void* data() const BOOST_ASIO_NOEXCEPT
+ {
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ if (size_ && debug_check_)
+ debug_check_();
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ return data_;
+ }
+
+ /// Get the size of the memory range.
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
+ {
+ return size_;
+ }
+
+ /// Move the start of the buffer by the specified number of bytes.
+ mutable_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT
+ {
+ std::size_t offset = n < size_ ? n : size_;
+ data_ = static_cast<char*>(data_) + offset;
+ size_ -= offset;
+ return *this;
+ }
+private:
void* data_;
std::size_t size_;
@@ -135,26 +154,10 @@ private:
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
};
-namespace detail {
-
-inline void* buffer_cast_helper(const mutable_buffer& b)
-{
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- if (b.size_ && b.debug_check_)
- b.debug_check_();
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- return b.data_;
-}
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
-inline std::size_t buffer_size_helper(const mutable_buffer& b)
-{
- return b.size_;
-}
-
-} // namespace detail
-
-/// Adapts a single modifiable buffer so that it meets the requirements of the
-/// MutableBufferSequence concept.
+/// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that
+/// it meets the requirements of the MutableBufferSequence concept.
class mutable_buffers_1
: public mutable_buffer
{
@@ -166,30 +169,40 @@ public:
typedef const mutable_buffer* const_iterator;
/// Construct to represent a given memory range.
- mutable_buffers_1(void* data, std::size_t size)
+ mutable_buffers_1(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
: mutable_buffer(data, size)
{
}
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ mutable_buffers_1(void* data, std::size_t size,
+ boost::asio::detail::function<void()> debug_check)
+ : mutable_buffer(data, size, debug_check)
+ {
+ }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
/// Construct to represent a single modifiable buffer.
- explicit mutable_buffers_1(const mutable_buffer& b)
+ explicit mutable_buffers_1(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
: mutable_buffer(b)
{
}
/// Get a random-access iterator to the first element.
- const_iterator begin() const
+ const_iterator begin() const BOOST_ASIO_NOEXCEPT
{
return this;
}
/// Get a random-access iterator for one past the last element.
- const_iterator end() const
+ const_iterator end() const BOOST_ASIO_NOEXCEPT
{
return begin() + 1;
}
};
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
/// Holds a buffer that cannot be modified.
/**
* The const_buffer class provides a safe representation of a buffer that cannot
@@ -198,38 +211,38 @@ public:
*
* @par Accessing Buffer Contents
*
- * The contents of a buffer may be accessed using the @ref buffer_size
- * and @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
*
* @code boost::asio::const_buffer b1 = ...;
- * std::size_t s1 = boost::asio::buffer_size(b1);
- * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
* @endcode
*
- * The boost::asio::buffer_cast function permits violations of type safety, so
- * uses of it in application code should be carefully considered.
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
*/
class const_buffer
{
public:
/// Construct an empty buffer.
- const_buffer()
+ const_buffer() BOOST_ASIO_NOEXCEPT
: data_(0),
size_(0)
{
}
/// Construct a buffer to represent a given memory range.
- const_buffer(const void* data, std::size_t size)
+ const_buffer(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
: data_(data),
size_(size)
{
}
/// Construct a non-modifiable buffer from a modifiable one.
- const_buffer(const mutable_buffer& b)
- : data_(boost::asio::detail::buffer_cast_helper(b)),
- size_(boost::asio::detail::buffer_size_helper(b))
+ const_buffer(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+ : data_(b.data()),
+ size_(b.size())
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
, debug_check_(b.get_debug_check())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
@@ -251,12 +264,32 @@ public:
}
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
-private:
- friend const void* boost::asio::detail::buffer_cast_helper(
- const const_buffer& b);
- friend std::size_t boost::asio::detail::buffer_size_helper(
- const const_buffer& b);
+ /// Get a pointer to the beginning of the memory range.
+ const void* data() const BOOST_ASIO_NOEXCEPT
+ {
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ if (size_ && debug_check_)
+ debug_check_();
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ return data_;
+ }
+ /// Get the size of the memory range.
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
+ {
+ return size_;
+ }
+
+ /// Move the start of the buffer by the specified number of bytes.
+ const_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT
+ {
+ std::size_t offset = n < size_ ? n : size_;
+ data_ = static_cast<const char*>(data_) + offset;
+ size_ -= offset;
+ return *this;
+ }
+
+private:
const void* data_;
std::size_t size_;
@@ -265,26 +298,10 @@ private:
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
};
-namespace detail {
-
-inline const void* buffer_cast_helper(const const_buffer& b)
-{
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- if (b.size_ && b.debug_check_)
- b.debug_check_();
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- return b.data_;
-}
-
-inline std::size_t buffer_size_helper(const const_buffer& b)
-{
- return b.size_;
-}
-
-} // namespace detail
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
-/// Adapts a single non-modifiable buffer so that it meets the requirements of
-/// the ConstBufferSequence concept.
+/// (Deprecated: Use 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
{
@@ -296,32 +313,78 @@ public:
typedef const const_buffer* const_iterator;
/// Construct to represent a given memory range.
- const_buffers_1(const void* data, std::size_t size)
+ const_buffers_1(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
: const_buffer(data, size)
{
}
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ const_buffers_1(const void* data, std::size_t size,
+ boost::asio::detail::function<void()> debug_check)
+ : const_buffer(data, size, debug_check)
+ {
+ }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
/// Construct to represent a single non-modifiable buffer.
- explicit const_buffers_1(const const_buffer& b)
+ explicit const_buffers_1(const const_buffer& b) BOOST_ASIO_NOEXCEPT
: const_buffer(b)
{
}
/// Get a random-access iterator to the first element.
- const_iterator begin() const
+ const_iterator begin() const BOOST_ASIO_NOEXCEPT
{
return this;
}
/// Get a random-access iterator for one past the last element.
- const_iterator end() const
+ const_iterator end() const BOOST_ASIO_NOEXCEPT
{
return begin() + 1;
}
};
-/// An implementation of both the ConstBufferSequence and MutableBufferSequence
-/// concepts to represent a null buffer sequence.
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Trait to determine whether a type satisfies the MutableBufferSequence
+/// requirements.
+template <typename T>
+struct is_mutable_buffer_sequence
+#if defined(GENERATING_DOCUMENTATION)
+ : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+ : boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// Trait to determine whether a type satisfies the ConstBufferSequence
+/// requirements.
+template <typename T>
+struct is_const_buffer_sequence
+#if defined(GENERATING_DOCUMENTATION)
+ : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+ : boost::asio::detail::is_buffer_sequence<T, const_buffer>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
+template <typename T>
+struct is_dynamic_buffer
+#if defined(GENERATING_DOCUMENTATION)
+ : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+ : boost::asio::detail::is_dynamic_buffer<T>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// (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
{
public:
@@ -332,13 +395,13 @@ public:
typedef const mutable_buffer* const_iterator;
/// Get a random-access iterator to the first element.
- const_iterator begin() const
+ const_iterator begin() const BOOST_ASIO_NOEXCEPT
{
return &buf_;
}
/// Get a random-access iterator for one past the last element.
- const_iterator end() const
+ const_iterator end() const BOOST_ASIO_NOEXCEPT
{
return &buf_;
}
@@ -347,61 +410,189 @@ private:
mutable_buffer buf_;
};
-/** @defgroup buffer_size boost::asio::buffer_size
+/** @defgroup buffer_sequence_begin boost::asio::buffer_sequence_begin
*
- * @brief The boost::asio::buffer_size function determines the total number of
- * bytes in a buffer or buffer sequence.
+ * @brief The boost::asio::buffer_sequence_begin function returns an iterator
+ * pointing to the first element in a buffer sequence.
*/
/*@{*/
-/// Get the number of bytes in a modifiable buffer.
-inline std::size_t buffer_size(const mutable_buffer& b)
+/// Get an iterator to the first element in a buffer sequence.
+inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b)
{
- return detail::buffer_size_helper(b);
+ return &b;
}
-/// Get the number of bytes in a modifiable buffer.
-inline std::size_t buffer_size(const mutable_buffers_1& b)
+/// Get an iterator to the first element in a buffer sequence.
+inline const const_buffer* buffer_sequence_begin(const const_buffer& b)
{
- return detail::buffer_size_helper(b);
+ return &b;
}
-/// Get the number of bytes in a non-modifiable buffer.
-inline std::size_t buffer_size(const const_buffer& b)
+#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/// Get an iterator to the first element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_begin(C& c) -> decltype(c.begin())
{
- return detail::buffer_size_helper(b);
+ return c.begin();
}
-/// Get the number of bytes in a non-modifiable buffer.
-inline std::size_t buffer_size(const const_buffers_1& b)
+/// Get an iterator to the first element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
{
- return detail::buffer_size_helper(b);
+ return c.begin();
}
-/// Get the total number of bytes in a buffer sequence.
-/**
- * The @c BufferSequence template parameter may meet either of the @c
- * ConstBufferSequence or @c MutableBufferSequence type requirements.
+#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+template <typename C>
+inline typename C::iterator buffer_sequence_begin(C& c)
+{
+ return c.begin();
+}
+
+template <typename C>
+inline typename C::const_iterator buffer_sequence_begin(const C& c)
+{
+ return c.begin();
+}
+
+#endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+/** @defgroup buffer_sequence_end boost::asio::buffer_sequence_end
+ *
+ * @brief The boost::asio::buffer_sequence_end function returns an iterator
+ * pointing to one past the end element in a buffer sequence.
*/
+/*@{*/
+
+/// Get an iterator to one past the end element in a buffer sequence.
+inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b)
+{
+ return &b + 1;
+}
+
+/// Get an iterator to one past the end element in a buffer sequence.
+inline const const_buffer* buffer_sequence_end(const const_buffer& b)
+{
+ return &b + 1;
+}
+
+#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/// Get an iterator to one past the end element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_end(C& c) -> decltype(c.end())
+{
+ return c.end();
+}
+
+/// Get an iterator to one past the end element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
+{
+ return c.end();
+}
+
+#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+template <typename C>
+inline typename C::iterator buffer_sequence_end(C& c)
+{
+ return c.end();
+}
+
+template <typename C>
+inline typename C::const_iterator buffer_sequence_end(const C& c)
+{
+ return c.end();
+}
+
+#endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+namespace detail {
+
+// Tag types used to select appropriately optimised overloads.
+struct one_buffer {};
+struct multiple_buffers {};
+
+// Helper trait to detect single buffers.
template <typename BufferSequence>
-inline std::size_t buffer_size(const BufferSequence& b)
+struct buffer_sequence_cardinality :
+ conditional<
+ is_same<BufferSequence, mutable_buffer>::value
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ || is_same<BufferSequence, mutable_buffers_1>::value
+ || is_same<BufferSequence, const_buffers_1>::value
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+ || is_same<BufferSequence, const_buffer>::value,
+ one_buffer, multiple_buffers>::type {};
+
+template <typename Iterator>
+inline std::size_t buffer_size(one_buffer,
+ Iterator begin, Iterator) BOOST_ASIO_NOEXCEPT
+{
+ return const_buffer(*begin).size();
+}
+
+template <typename Iterator>
+inline std::size_t buffer_size(multiple_buffers,
+ Iterator begin, Iterator end) BOOST_ASIO_NOEXCEPT
{
std::size_t total_buffer_size = 0;
- typename BufferSequence::const_iterator iter = b.begin();
- typename BufferSequence::const_iterator end = b.end();
+ Iterator iter = begin;
for (; iter != end; ++iter)
- total_buffer_size += detail::buffer_size_helper(*iter);
+ {
+ const_buffer b(*iter);
+ total_buffer_size += b.size();
+ }
return total_buffer_size;
}
-/*@}*/
+} // namespace detail
+
+/// Get the total number of bytes in a buffer sequence.
+/**
+ * The @c buffer_size function determines the total size of all buffers in the
+ * buffer sequence, as if computed as follows:
+ *
+ * @code size_t total_size = 0;
+ * auto i = boost::asio::buffer_sequence_begin(buffers);
+ * auto end = boost::asio::buffer_sequence_end(buffers);
+ * for (; i != end; ++i)
+ * {
+ * const_buffer b(*i);
+ * total_size += b.size();
+ * }
+ * return total_size; @endcode
+ *
+ * The @c BufferSequence template parameter may meet either of the @c
+ * ConstBufferSequence or @c MutableBufferSequence type requirements.
+ */
+template <typename BufferSequence>
+inline std::size_t buffer_size(const BufferSequence& b) BOOST_ASIO_NOEXCEPT
+{
+ return detail::buffer_size(
+ detail::buffer_sequence_cardinality<BufferSequence>(),
+ boost::asio::buffer_sequence_begin(b),
+ boost::asio::buffer_sequence_end(b));
+}
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
/** @defgroup buffer_cast boost::asio::buffer_cast
*
- * @brief The boost::asio::buffer_cast function is used to obtain a pointer to
- * the underlying memory region associated with a buffer.
+ * @brief (Deprecated: Use the @c data() member function.) The
+ * boost::asio::buffer_cast function is used to obtain a pointer to the
+ * underlying memory region associated with a buffer.
*
* @par Examples:
*
@@ -422,30 +613,32 @@ inline std::size_t buffer_size(const BufferSequence& b)
/// Cast a non-modifiable buffer to a specified pointer to POD type.
template <typename PointerToPodType>
-inline PointerToPodType buffer_cast(const mutable_buffer& b)
+inline PointerToPodType buffer_cast(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
{
- return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+ return static_cast<PointerToPodType>(b.data());
}
/// Cast a non-modifiable buffer to a specified pointer to POD type.
template <typename PointerToPodType>
-inline PointerToPodType buffer_cast(const const_buffer& b)
+inline PointerToPodType buffer_cast(const const_buffer& b) BOOST_ASIO_NOEXCEPT
{
- return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+ return static_cast<PointerToPodType>(b.data());
}
/*@}*/
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
/// Create a new modifiable buffer that is offset from the start of another.
/**
* @relates mutable_buffer
*/
-inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
+inline mutable_buffer operator+(const mutable_buffer& b,
+ std::size_t n) BOOST_ASIO_NOEXCEPT
{
- if (start > buffer_size(b))
- return mutable_buffer();
- char* new_data = buffer_cast<char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
+ std::size_t offset = n < b.size() ? n : b.size();
+ char* new_data = static_cast<char*>(b.data()) + offset;
+ std::size_t new_size = b.size() - offset;
return mutable_buffer(new_data, new_size
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
@@ -457,29 +650,22 @@ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
/**
* @relates mutable_buffer
*/
-inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
+inline mutable_buffer operator+(std::size_t n,
+ const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
{
- if (start > buffer_size(b))
- return mutable_buffer();
- char* new_data = buffer_cast<char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return mutable_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
+ return b + n;
}
/// Create a new non-modifiable buffer that is offset from the start of another.
/**
* @relates const_buffer
*/
-inline const_buffer operator+(const const_buffer& b, std::size_t start)
+inline const_buffer operator+(const const_buffer& b,
+ std::size_t n) BOOST_ASIO_NOEXCEPT
{
- if (start > buffer_size(b))
- return const_buffer();
- const char* new_data = buffer_cast<const char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
+ std::size_t offset = n < b.size() ? n : b.size();
+ const char* new_data = static_cast<const char*>(b.data()) + offset;
+ std::size_t new_size = b.size() - offset;
return const_buffer(new_data, new_size
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
@@ -491,17 +677,10 @@ inline const_buffer operator+(const const_buffer& b, std::size_t start)
/**
* @relates const_buffer
*/
-inline const_buffer operator+(std::size_t start, const const_buffer& b)
+inline const_buffer operator+(std::size_t n,
+ const const_buffer& b) BOOST_ASIO_NOEXCEPT
{
- if (start > buffer_size(b))
- return const_buffer();
- const char* new_data = buffer_cast<const char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return const_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
+ return b + n;
}
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
@@ -586,32 +765,33 @@ private:
*
* @par Accessing Buffer Contents
*
- * The contents of a buffer may be accessed using the @ref buffer_size and
- * @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
*
* @code boost::asio::mutable_buffer b1 = ...;
- * std::size_t s1 = boost::asio::buffer_size(b1);
- * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
*
* boost::asio::const_buffer b2 = ...;
- * std::size_t s2 = boost::asio::buffer_size(b2);
- * const void* p2 = boost::asio::buffer_cast<const void*>(b2); @endcode
+ * std::size_t s2 = b2.size();
+ * const void* p2 = b2.data(); @endcode
*
- * The boost::asio::buffer_cast function permits violations of type safety, so
+ * The @c data() member function permits violations of type safety, so
* uses of it in application code should be carefully considered.
*
- * For convenience, the @ref buffer_size function also works on 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.
+ * For convenience, a @ref 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.
*
* @par Buffer Copying
*
* The @ref buffer_copy function may be used to copy raw bytes between
* individual buffers and buffer sequences.
- *
- * In particular, when used with the @ref buffer_size, the @ref buffer_copy
- * function can be used to linearise a sequence of buffers. For example:
+*
+ * In particular, when used with the @ref buffer_size function, the @ref
+ * buffer_copy function can be used to linearise a sequence of buffers. For
+ * example:
*
* @code vector<const_buffer> buffers = ...;
*
@@ -700,29 +880,38 @@ private:
*/
/*@{*/
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_MUTABLE_BUFFER mutable_buffer
+# define BOOST_ASIO_CONST_BUFFER const_buffer
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_1
+# define BOOST_ASIO_CONST_BUFFER const_buffers_1
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+
/// Create a new modifiable buffer from an existing buffer.
/**
- * @returns <tt>mutable_buffers_1(b)</tt>.
+ * @returns <tt>mutable_buffer(b)</tt>.
*/
-inline mutable_buffers_1 buffer(const mutable_buffer& b)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(b);
+ return BOOST_ASIO_MUTABLE_BUFFER(b);
}
/// Create a new modifiable buffer from an existing buffer.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
- * buffer_cast<void*>(b),
- * min(buffer_size(b), max_size_in_bytes)); @endcode
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ * b.data(),
+ * min(b.size(), max_size_in_bytes)); @endcode
*/
-inline mutable_buffers_1 buffer(const mutable_buffer& b,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(buffer_cast<void*>(b),
- buffer_size(b) < max_size_in_bytes
- ? buffer_size(b) : max_size_in_bytes
+ return BOOST_ASIO_MUTABLE_BUFFER(
+ mutable_buffer(b.data(),
+ b.size() < max_size_in_bytes
+ ? b.size() : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
@@ -731,110 +920,110 @@ inline mutable_buffers_1 buffer(const mutable_buffer& b,
/// Create a new non-modifiable buffer from an existing buffer.
/**
- * @returns <tt>const_buffers_1(b)</tt>.
+ * @returns <tt>const_buffer(b)</tt>.
*/
-inline const_buffers_1 buffer(const const_buffer& b)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const const_buffer& b) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(b);
+ return BOOST_ASIO_CONST_BUFFER(b);
}
/// Create a new non-modifiable buffer from an existing buffer.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
- * buffer_cast<const void*>(b),
- * min(buffer_size(b), max_size_in_bytes)); @endcode
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ * b.data(),
+ * min(b.size(), max_size_in_bytes)); @endcode
*/
-inline const_buffers_1 buffer(const const_buffer& b,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(const const_buffer& b,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(buffer_cast<const void*>(b),
- buffer_size(b) < max_size_in_bytes
- ? buffer_size(b) : max_size_in_bytes
+ return BOOST_ASIO_CONST_BUFFER(b.data(),
+ b.size() < max_size_in_bytes
+ ? b.size() : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
+ , b.get_debug_check()
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
/// Create a new modifiable buffer that represents the given memory range.
/**
- * @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
+ * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.
*/
-inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(void* data,
+ std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
+ return BOOST_ASIO_MUTABLE_BUFFER(data, size_in_bytes);
}
/// Create a new non-modifiable buffer that represents the given memory range.
/**
- * @returns <tt>const_buffers_1(data, size_in_bytes)</tt>.
+ * @returns <tt>const_buffer(data, size_in_bytes)</tt>.
*/
-inline const_buffers_1 buffer(const void* data,
- std::size_t size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(const void* data,
+ std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(const_buffer(data, size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data, size_in_bytes);
}
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* static_cast<void*>(data),
* N * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(PodType (&data)[N])
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
+ return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));
}
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* static_cast<void*>(data),
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(PodType (&data)[N],
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N],
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data,
- N * sizeof(PodType) < max_size_in_bytes
- ? N * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_MUTABLE_BUFFER(data,
+ N * sizeof(PodType) < max_size_in_bytes
+ ? N * sizeof(PodType) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* static_cast<const void*>(data),
* N * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const PodType (&data)[N])
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
+ return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType));
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* static_cast<const void*>(data),
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const PodType (&data)[N],
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(const PodType (&data)[N],
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data,
- N * sizeof(PodType) < max_size_in_bytes
- ? N * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data,
+ N * sizeof(PodType) < max_size_in_bytes
+ ? N * sizeof(PodType) : max_size_in_bytes);
}
#if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
@@ -860,14 +1049,14 @@ template <>
struct buffer_types_base<false>
{
typedef mutable_buffer buffer_type;
- typedef mutable_buffers_1 container_type;
+ typedef BOOST_ASIO_MUTABLE_BUFFER container_type;
};
template <>
struct buffer_types_base<true>
{
typedef const_buffer buffer_type;
- typedef const_buffers_1 container_type;
+ typedef BOOST_ASIO_CONST_BUFFER container_type;
};
template <typename PodType>
@@ -880,7 +1069,7 @@ struct buffer_types
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
-buffer(boost::array<PodType, N>& data)
+buffer(boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
buffer_type;
@@ -892,7 +1081,8 @@ buffer(boost::array<PodType, N>& data)
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
-buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
+buffer(boost::array<PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
buffer_type;
@@ -908,200 +1098,195 @@ buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_MUTABLE_BUFFER(
+ data.c_array(), data.size() * sizeof(PodType));
}
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(boost::array<PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.c_array(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_MUTABLE_BUFFER(data.c_array(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ boost::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(boost::array<const PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
#endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(const boost::array<PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
#if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(std::array<PodType, N>& data)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.data(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));
}
/// Create a new modifiable buffer that represents the given POD array.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline mutable_buffers_1 buffer(std::array<PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::array<PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.data(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_MUTABLE_BUFFER(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(std::array<const PodType, N>& data)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ std::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(std::array<const PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(std::array<const PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const std::array<PodType, N>& data)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(), data.size() * sizeof(PodType)));
+ return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
}
/// Create a new non-modifiable buffer that represents the given POD array.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.data(),
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
-inline const_buffers_1 buffer(const std::array<PodType, N>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(const std::array<PodType, N>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(),
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes));
+ return BOOST_ASIO_CONST_BUFFER(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes);
}
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
/// Create a new modifiable buffer that represents the given POD vector.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.size() ? &data[0] : 0,
* data.size() * sizeof(PodType)); @endcode
*
@@ -1109,22 +1294,23 @@ inline const_buffers_1 buffer(const std::array<PodType, N>& data,
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
-inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
+ return BOOST_ASIO_MUTABLE_BUFFER(
+ data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::vector<PodType, Allocator>::iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::vector<PodType, Allocator>::iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
/// Create a new modifiable buffer that represents the given POD vector.
/**
- * @returns A mutable_buffers_1 value equivalent to:
- * @code mutable_buffers_1(
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
* data.size() ? &data[0] : 0,
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*
@@ -1132,25 +1318,24 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
-inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::vector<PodType, Allocator>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return mutable_buffers_1(
- mutable_buffer(data.size() ? &data[0] : 0,
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes
+ return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::vector<PodType, Allocator>::iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::vector<PodType, Allocator>::iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
/// Create a new non-modifiable buffer that represents the given POD vector.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.size() ? &data[0] : 0,
* data.size() * sizeof(PodType)); @endcode
*
@@ -1158,23 +1343,23 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
-inline const_buffers_1 buffer(
- const std::vector<PodType, Allocator>& data)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
+ return BOOST_ASIO_CONST_BUFFER(
+ data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::vector<PodType, Allocator>::const_iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::vector<PodType, Allocator>::const_iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
/// Create a new non-modifiable buffer that represents the given POD vector.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
* data.size() ? &data[0] : 0,
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*
@@ -1182,527 +1367,640 @@ inline const_buffers_1 buffer(
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
-inline const_buffers_1 buffer(
- const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const std::vector<PodType, Allocator>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.size() ? &data[0] : 0,
- data.size() * sizeof(PodType) < max_size_in_bytes
- ? data.size() * sizeof(PodType) : max_size_in_bytes
+ return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::vector<PodType, Allocator>::const_iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::vector<PodType, Allocator>::const_iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
-/// Create a new non-modifiable buffer that represents the given string.
+/// Create a new modifiable buffer that represents the given string.
/**
- * @returns <tt>const_buffers_1(data.data(), data.size() * sizeof(Elem))</tt>.
+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,
+ * data.size() * sizeof(Elem))</tt>.
*
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
-inline const_buffers_1 buffer(
- const std::basic_string<Elem, Traits, Allocator>& data)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem)
+ return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(Elem)
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::basic_string<Elem, Traits, Allocator>::const_iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
/// Create a new non-modifiable buffer that represents the given string.
/**
- * @returns A const_buffers_1 value equivalent to:
- * @code const_buffers_1(
- * data.data(),
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ * data.size() ? &data[0] : 0,
* min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
*
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
-inline const_buffers_1 buffer(
- const std::basic_string<Elem, Traits, Allocator>& data,
- std::size_t max_size_in_bytes)
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+ std::basic_string<Elem, Traits, Allocator>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return const_buffers_1(
- const_buffer(data.data(),
- data.size() * sizeof(Elem) < max_size_in_bytes
- ? data.size() * sizeof(Elem) : max_size_in_bytes
+ return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(Elem) < max_size_in_bytes
+ ? data.size() * sizeof(Elem) : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<
- typename std::basic_string<Elem, Traits, Allocator>::const_iterator
- >(data.begin())
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- ));
+ );
}
-/*@}*/
-
-/** @defgroup buffer_copy boost::asio::buffer_copy
- *
- * @brief The boost::asio::buffer_copy function is used to copy bytes from a
- * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
- *
- * The @c buffer_copy function is available in two forms:
- *
- * @li A 2-argument form: @c buffer_copy(target, source)
- *
- * @li A 3-argument form: @c 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:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c If specified, @c max_bytes_to_copy.
- *
- * This prevents buffer overflow, regardless of the buffer sizes used in the
- * copy operation.
- *
- * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
- * consequently it cannot be used to copy between overlapping memory regions.
- */
-/*@{*/
-
-/// Copies bytes from a source buffer to a target buffer.
+/// Create a new non-modifiable buffer that represents the given string.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
+ * @returns <tt>const_buffer(data.data(), data.size() * sizeof(Elem))</tt>.
*
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
*/
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const const_buffer& source)
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- using namespace std; // For memcpy.
- std::size_t target_size = buffer_size(target);
- std::size_t source_size = buffer_size(source);
- std::size_t n = target_size < source_size ? target_size : source_size;
- memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
- return n;
+ return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+ >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
}
-/// Copies bytes from a source buffer to a target buffer.
+/// Create a new non-modifiable buffer that represents the given string.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ * data.data(),
+ * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
*
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
*/
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const const_buffers_1& source)
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ const std::basic_string<Elem, Traits, Allocator>& data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(target, static_cast<const const_buffer&>(source));
+ return BOOST_ASIO_CONST_BUFFER(data.data(),
+ data.size() * sizeof(Elem) < max_size_in_bytes
+ ? data.size() * sizeof(Elem) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+ >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
}
-/// Copies bytes from a source buffer to a target buffer.
+#if defined(BOOST_ASIO_HAS_STD_STRING_VIEW) \
+ || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer that represents the given string_view.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,
+ * data.size() * sizeof(Elem))</tt>.
*/
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const mutable_buffer& source)
+template <typename Elem, typename Traits>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ basic_string_view<Elem, Traits> data) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(target, const_buffer(source));
+ return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(Elem)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , detail::buffer_debug_check<
+ typename basic_string_view<Elem, Traits>::iterator
+ >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
}
-/// Copies bytes from a source buffer to a target buffer.
+/// Create a new non-modifiable buffer that represents the given string.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ * data.size() ? &data[0] : 0,
+ * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
*/
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const mutable_buffers_1& source)
+template <typename Elem, typename Traits>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+ basic_string_view<Elem, Traits> data,
+ std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(target, const_buffer(source));
+ return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+ data.size() * sizeof(Elem) < max_size_in_bytes
+ ? data.size() * sizeof(Elem) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , detail::buffer_debug_check<
+ typename basic_string_view<Elem, Traits>::iterator
+ >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
}
-/// Copies bytes from a source buffer sequence to a target buffer.
+#endif // defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
+ // || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+/// Adapt a basic_string to the DynamicBuffer requirements.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * Requires that <tt>sizeof(Elem) == 1</tt>.
*/
-template <typename ConstBufferSequence>
-std::size_t buffer_copy(const mutable_buffer& target,
- const ConstBufferSequence& source)
+template <typename Elem, typename Traits, typename Allocator>
+class dynamic_string_buffer
{
- std::size_t total_bytes_copied = 0;
+public:
+ /// The type used to represent the input sequence as a list of buffers.
+ typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+
+ /// The type used to represent the output sequence as a list of buffers.
+ typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
+
+ /// Construct a dynamic buffer from a string.
+ /**
+ * @param 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
+ * dynamic_string_buffer object is destroyed.
+ *
+ * @param maximum_size Specifies a maximum size for the buffer, in bytes.
+ */
+ explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s,
+ std::size_t maximum_size =
+ (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+ : string_(s),
+ size_(string_.size()),
+ max_size_(maximum_size)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move construct a dynamic buffer.
+ dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT
+ : string_(other.string_),
+ size_(other.size_),
+ max_size_(other.max_size_)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- typename ConstBufferSequence::const_iterator source_iter = source.begin();
- typename ConstBufferSequence::const_iterator source_end = source.end();
+ /// Get the size of the input sequence.
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
+ {
+ return size_;
+ }
- for (mutable_buffer target_buffer(target);
- buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
+ /// Get the maximum size of the dynamic buffer.
+ /**
+ * @returns The allowed maximum of the sum of the sizes of the input sequence
+ * and output sequence.
+ */
+ std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
- const_buffer source_buffer(*source_iter);
- std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
- total_bytes_copied += bytes_copied;
- target_buffer = target_buffer + bytes_copied;
+ return max_size_;
}
- return total_bytes_copied;
-}
+ /// Get the current capacity of the dynamic buffer.
+ /**
+ * @returns The current total capacity of the buffer, i.e. for both the input
+ * sequence and output sequence.
+ */
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+ {
+ return string_.capacity();
+ }
+
+ /// Get a list of buffers that represents the input sequence.
+ /**
+ * @returns An object of type @c const_buffers_type that satisfies
+ * ConstBufferSequence requirements, representing the basic_string memory in
+ * input sequence.
+ *
+ * @note The returned object is invalidated by any @c dynamic_string_buffer
+ * or @c basic_string member function that modifies the input sequence or
+ * output sequence.
+ */
+ const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+ {
+ return const_buffers_type(boost::asio::buffer(string_, size_));
+ }
+
+ /// Get a list of buffers that represents the output sequence, with the given
+ /// size.
+ /**
+ * Ensures that the output sequence can accommodate @c n bytes, resizing the
+ * basic_string object as necessary.
+ *
+ * @returns An object of type @c mutable_buffers_type that satisfies
+ * MutableBufferSequence requirements, representing basic_string memory
+ * at the start of the output sequence of size @c n.
+ *
+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+ *
+ * @note The returned object is invalidated by any @c dynamic_string_buffer
+ * or @c basic_string member function that modifies the input sequence or
+ * output sequence.
+ */
+ mutable_buffers_type prepare(std::size_t n)
+ {
+ if (size () > max_size() || max_size() - size() < n)
+ {
+ std::length_error ex("dynamic_string_buffer too long");
+ boost::asio::detail::throw_exception(ex);
+ }
+
+ string_.resize(size_ + n);
+
+ return boost::asio::buffer(boost::asio::buffer(string_) + size_, n);
+ }
+
+ /// Move bytes from the output sequence to the input sequence.
+ /**
+ * @param 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 <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
+ * no intervening operations that modify the input or output sequence.
+ *
+ * @note If @c 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.
+ */
+ void commit(std::size_t n)
+ {
+ size_ += (std::min)(n, string_.size() - size_);
+ string_.resize(size_);
+ }
+
+ /// Remove characters from the input sequence.
+ /**
+ * Removes @c n characters from the beginning of the input sequence.
+ *
+ * @note If @c n is greater than the size of the input sequence, the entire
+ * input sequence is consumed and no error is issued.
+ */
+ void consume(std::size_t n)
+ {
+ std::size_t consume_length = (std::min)(n, size_);
+ string_.erase(0, consume_length);
+ size_ -= consume_length;
+ }
+
+private:
+ std::basic_string<Elem, Traits, Allocator>& string_;
+ std::size_t size_;
+ const std::size_t max_size_;
+};
-/// Copies bytes from a source buffer to a target buffer.
+/// Adapt a vector to the DynamicBuffer requirements.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * Requires that <tt>sizeof(Elem) == 1</tt>.
*/
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const const_buffer& source)
+template <typename Elem, typename Allocator>
+class dynamic_vector_buffer
{
- return buffer_copy(static_cast<const mutable_buffer&>(target), source);
-}
+public:
+ /// The type used to represent the input sequence as a list of buffers.
+ typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+
+ /// The type used to represent the output sequence as a list of buffers.
+ typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
+
+ /// Construct a dynamic buffer from a string.
+ /**
+ * @param 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
+ * dynamic_vector_buffer object is destroyed.
+ *
+ * @param maximum_size Specifies a maximum size for the buffer, in bytes.
+ */
+ explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v,
+ std::size_t maximum_size =
+ (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+ : vector_(v),
+ size_(vector_.size()),
+ max_size_(maximum_size)
+ {
+ }
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move construct a dynamic buffer.
+ dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT
+ : vector_(other.vector_),
+ size_(other.size_),
+ max_size_(other.max_size_)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Get the size of the input sequence.
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
+ {
+ return size_;
+ }
+
+ /// Get the maximum size of the dynamic buffer.
+ /**
+ * @returns The allowed maximum of the sum of the sizes of the input sequence
+ * and output sequence.
+ */
+ std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+ {
+ return max_size_;
+ }
+
+ /// Get the current capacity of the dynamic buffer.
+ /**
+ * @returns The current total capacity of the buffer, i.e. for both the input
+ * sequence and output sequence.
+ */
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+ {
+ return vector_.capacity();
+ }
+
+ /// Get a list of buffers that represents the input sequence.
+ /**
+ * @returns An object of type @c const_buffers_type that satisfies
+ * ConstBufferSequence requirements, representing the basic_string memory in
+ * input sequence.
+ *
+ * @note The returned object is invalidated by any @c dynamic_vector_buffer
+ * or @c basic_string member function that modifies the input sequence or
+ * output sequence.
+ */
+ const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+ {
+ return const_buffers_type(boost::asio::buffer(vector_, size_));
+ }
+
+ /// Get a list of buffers that represents the output sequence, with the given
+ /// size.
+ /**
+ * Ensures that the output sequence can accommodate @c n bytes, resizing the
+ * basic_string object as necessary.
+ *
+ * @returns An object of type @c mutable_buffers_type that satisfies
+ * MutableBufferSequence requirements, representing basic_string memory
+ * at the start of the output sequence of size @c n.
+ *
+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+ *
+ * @note The returned object is invalidated by any @c dynamic_vector_buffer
+ * or @c basic_string member function that modifies the input sequence or
+ * output sequence.
+ */
+ mutable_buffers_type prepare(std::size_t n)
+ {
+ if (size () > max_size() || max_size() - size() < n)
+ {
+ std::length_error ex("dynamic_vector_buffer too long");
+ boost::asio::detail::throw_exception(ex);
+ }
+
+ vector_.resize(size_ + n);
+
+ return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n);
+ }
+
+ /// Move bytes from the output sequence to the input sequence.
+ /**
+ * @param 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 <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
+ * no intervening operations that modify the input or output sequence.
+ *
+ * @note If @c 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.
+ */
+ void commit(std::size_t n)
+ {
+ size_ += (std::min)(n, vector_.size() - size_);
+ vector_.resize(size_);
+ }
+
+ /// Remove characters from the input sequence.
+ /**
+ * Removes @c n characters from the beginning of the input sequence.
+ *
+ * @note If @c n is greater than the size of the input sequence, the entire
+ * input sequence is consumed and no error is issued.
+ */
+ void consume(std::size_t n)
+ {
+ std::size_t consume_length = (std::min)(n, size_);
+ vector_.erase(vector_.begin(), vector_.begin() + consume_length);
+ size_ -= consume_length;
+ }
+
+private:
+ std::vector<Elem, Allocator>& vector_;
+ std::size_t size_;
+ const std::size_t max_size_;
+};
+
+/** @defgroup dynamic_buffer boost::asio::dynamic_buffer
*
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @brief The boost::asio::dynamic_buffer function is used to create a
+ * dynamically resized buffer from a @c std::basic_string or @c std::vector.
+ */
+/*@{*/
+
+/// Create a new dynamic buffer that represents the given string.
+/**
+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>.
*/
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const const_buffers_1& source)
+template <typename Elem, typename Traits, typename Allocator>
+inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
+ std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(static_cast<const mutable_buffer&>(target),
- static_cast<const const_buffer&>(source));
+ return dynamic_string_buffer<Elem, Traits, Allocator>(data);
}
-/// Copies bytes from a source buffer to a target buffer.
+/// Create a new dynamic buffer that represents the given string.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,
+ * max_size)</tt>.
*/
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const mutable_buffer& source)
+template <typename Elem, typename Traits, typename Allocator>
+inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
+ std::basic_string<Elem, Traits, Allocator>& data,
+ std::size_t max_size) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(static_cast<const mutable_buffer&>(target),
- const_buffer(source));
+ return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);
}
-/// Copies bytes from a source buffer to a target buffer.
+/// Create a new dynamic buffer that represents the given vector.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.
*/
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const mutable_buffers_1& source)
+template <typename Elem, typename Allocator>
+inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
+ std::vector<Elem, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(static_cast<const mutable_buffer&>(target),
- const_buffer(source));
+ return dynamic_vector_buffer<Elem, Allocator>(data);
}
-/// Copies bytes from a source buffer sequence to a target buffer.
+/// Create a new dynamic buffer that represents the given vector.
/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.
*/
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const ConstBufferSequence& source)
+template <typename Elem, typename Allocator>
+inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
+ std::vector<Elem, Allocator>& data,
+ std::size_t max_size) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(static_cast<const mutable_buffer&>(target), source);
+ return dynamic_vector_buffer<Elem, Allocator>(data, max_size);
}
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
+/*@}*/
+
+/** @defgroup buffer_copy boost::asio::buffer_copy
*
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
+ * @brief The boost::asio::buffer_copy function is used to copy bytes from a
+ * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
*
- * @returns The number of bytes copied.
+ * The @c buffer_copy function is available in two forms:
*
- * @note The number of bytes copied is the lesser of:
+ * @li A 2-argument form: @c buffer_copy(target, source)
+ *
+ * @li A 3-argument form: @c 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:
*
* @li @c buffer_size(target)
*
* @li @c buffer_size(source)
*
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
+ * @li @c If specified, @c max_bytes_to_copy.
+ *
+ * This prevents buffer overflow, regardless of the buffer sizes used in the
+ * copy operation.
+ *
+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
+ * consequently it cannot be used to copy between overlapping memory regions.
*/
-template <typename MutableBufferSequence>
-std::size_t buffer_copy(const MutableBufferSequence& target,
+/*@{*/
+
+namespace detail {
+
+inline std::size_t buffer_copy_1(const mutable_buffer& target,
const const_buffer& source)
{
- std::size_t total_bytes_copied = 0;
+ using namespace std; // For memcpy.
+ std::size_t target_size = target.size();
+ std::size_t source_size = source.size();
+ std::size_t n = target_size < source_size ? target_size : source_size;
+ if (n > 0)
+ memcpy(target.data(), source.data(), n);
+ return n;
+}
- typename MutableBufferSequence::const_iterator target_iter = target.begin();
- typename MutableBufferSequence::const_iterator target_end = target.end();
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+ TargetIterator target_begin, TargetIterator,
+ SourceIterator source_begin, SourceIterator) BOOST_ASIO_NOEXCEPT
+{
+ return (buffer_copy_1)(*target_begin, *source_begin);
+}
- for (const_buffer source_buffer(source);
- buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+ TargetIterator target_begin, TargetIterator,
+ SourceIterator source_begin, SourceIterator,
+ std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
+{
+ return (buffer_copy_1)(*target_begin,
+ boost::asio::buffer(*source_begin, max_bytes_to_copy));
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(one_buffer, multiple_buffers,
+ TargetIterator target_begin, TargetIterator,
+ SourceIterator source_begin, SourceIterator source_end,
+ std::size_t max_bytes_to_copy
+ = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+{
+ std::size_t total_bytes_copied = 0;
+ SourceIterator source_iter = source_begin;
+
+ for (mutable_buffer target_buffer(
+ boost::asio::buffer(*target_begin, max_bytes_to_copy));
+ target_buffer.size() && source_iter != source_end; ++source_iter)
{
- mutable_buffer target_buffer(*target_iter);
- std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+ const_buffer source_buffer(*source_iter);
+ std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
total_bytes_copied += bytes_copied;
- source_buffer = source_buffer + bytes_copied;
+ target_buffer += bytes_copied;
}
return total_bytes_copied;
}
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const const_buffers_1& source)
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, one_buffer,
+ TargetIterator target_begin, TargetIterator target_end,
+ SourceIterator source_begin, SourceIterator,
+ std::size_t max_bytes_to_copy
+ = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(target, static_cast<const const_buffer&>(source));
-}
+ std::size_t total_bytes_copied = 0;
+ TargetIterator target_iter = target_begin;
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const mutable_buffer& source)
-{
- return buffer_copy(target, const_buffer(source));
-}
+ for (const_buffer source_buffer(
+ boost::asio::buffer(*source_begin, max_bytes_to_copy));
+ source_buffer.size() && target_iter != target_end; ++target_iter)
+ {
+ mutable_buffer target_buffer(*target_iter);
+ std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
+ total_bytes_copied += bytes_copied;
+ source_buffer += bytes_copied;
+ }
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const mutable_buffers_1& source)
-{
- return buffer_copy(target, const_buffer(source));
+ return total_bytes_copied;
}
-/// Copies bytes from a source buffer sequence to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence, typename ConstBufferSequence>
-std::size_t buffer_copy(const MutableBufferSequence& target,
- const ConstBufferSequence& source)
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
+ TargetIterator target_begin, TargetIterator target_end,
+ SourceIterator source_begin, SourceIterator source_end) BOOST_ASIO_NOEXCEPT
{
std::size_t total_bytes_copied = 0;
- typename MutableBufferSequence::const_iterator target_iter = target.begin();
- typename MutableBufferSequence::const_iterator target_end = target.end();
+ TargetIterator target_iter = target_begin;
std::size_t target_buffer_offset = 0;
- typename ConstBufferSequence::const_iterator source_iter = source.begin();
- typename ConstBufferSequence::const_iterator source_end = source.end();
+ SourceIterator source_iter = source_begin;
std::size_t source_buffer_offset = 0;
while (target_iter != target_end && source_iter != source_end)
@@ -1713,10 +2011,10 @@ std::size_t buffer_copy(const MutableBufferSequence& target,
const_buffer source_buffer =
const_buffer(*source_iter) + source_buffer_offset;
- std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+ std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
total_bytes_copied += bytes_copied;
- if (bytes_copied == buffer_size(target_buffer))
+ if (bytes_copied == target_buffer.size())
{
++target_iter;
target_buffer_offset = 0;
@@ -1724,7 +2022,7 @@ std::size_t buffer_copy(const MutableBufferSequence& target,
else
target_buffer_offset += bytes_copied;
- if (bytes_copied == buffer_size(source_buffer))
+ if (bytes_copied == source_buffer.size())
{
++source_iter;
source_buffer_offset = 0;
@@ -1736,409 +2034,63 @@ std::size_t buffer_copy(const MutableBufferSequence& target,
return total_bytes_copied;
}
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const const_buffer& source, std::size_t max_bytes_to_copy)
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
+ TargetIterator target_begin, TargetIterator target_end,
+ SourceIterator source_begin, SourceIterator source_end,
+ std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const const_buffers_1& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const mutable_buffer& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ std::size_t total_bytes_copied = 0;
-/// Copies a limited number of bytes from a source buffer sequence to a target
-/// buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffer& target,
- const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ TargetIterator target_iter = target_begin;
+ std::size_t target_buffer_offset = 0;
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const const_buffer& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ SourceIterator source_iter = source_begin;
+ std::size_t source_buffer_offset = 0;
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const const_buffers_1& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ while (total_bytes_copied != max_bytes_to_copy
+ && target_iter != target_end && source_iter != source_end)
+ {
+ mutable_buffer target_buffer =
+ mutable_buffer(*target_iter) + target_buffer_offset;
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const mutable_buffer& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ const_buffer source_buffer =
+ const_buffer(*source_iter) + source_buffer_offset;
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ std::size_t bytes_copied = (buffer_copy_1)(
+ target_buffer, boost::asio::buffer(source_buffer,
+ max_bytes_to_copy - total_bytes_copied));
+ total_bytes_copied += bytes_copied;
-/// Copies a limited number of bytes from a source buffer sequence to a target
-/// buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
- const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
+ if (bytes_copied == target_buffer.size())
+ {
+ ++target_iter;
+ target_buffer_offset = 0;
+ }
+ else
+ target_buffer_offset += bytes_copied;
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const const_buffer& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
+ if (bytes_copied == source_buffer.size())
+ {
+ ++source_iter;
+ source_buffer_offset = 0;
+ }
+ else
+ source_buffer_offset += bytes_copied;
+ }
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const const_buffers_1& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(target, buffer(source, max_bytes_to_copy));
+ return total_bytes_copied;
}
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const mutable_buffer& source, std::size_t max_bytes_to_copy)
-{
- return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
+} // namespace detail
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
+/// Copies bytes from a source buffer sequence to a target buffer sequence.
/**
* @param target A modifiable buffer sequence representing the memory regions to
* which the bytes will be copied.
*
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
+ * @param source A non-modifiable buffer sequence representing the memory
+ * regions from which the bytes will be copied.
*
* @returns The number of bytes copied.
*
@@ -2148,16 +2100,20 @@ inline std::size_t buffer_copy(const MutableBufferSequence& target,
*
* @li @c buffer_size(source)
*
- * @li @c max_bytes_to_copy
- *
* This function is implemented in terms of @c memcpy, and consequently it
* cannot be used to copy between overlapping memory regions.
*/
-template <typename MutableBufferSequence>
+template <typename MutableBufferSequence, typename ConstBufferSequence>
inline std::size_t buffer_copy(const MutableBufferSequence& target,
- const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
+ const ConstBufferSequence& source) BOOST_ASIO_NOEXCEPT
{
- return buffer_copy(target, buffer(source, max_bytes_to_copy));
+ return detail::buffer_copy(
+ detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+ detail::buffer_sequence_cardinality<ConstBufferSequence>(),
+ boost::asio::buffer_sequence_begin(target),
+ boost::asio::buffer_sequence_end(target),
+ boost::asio::buffer_sequence_begin(source),
+ boost::asio::buffer_sequence_end(source));
}
/// Copies a limited number of bytes from a source buffer sequence to a target
@@ -2185,50 +2141,17 @@ inline std::size_t buffer_copy(const MutableBufferSequence& target,
* cannot be used to copy between overlapping memory regions.
*/
template <typename MutableBufferSequence, typename ConstBufferSequence>
-std::size_t buffer_copy(const MutableBufferSequence& target,
- const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
-{
- std::size_t total_bytes_copied = 0;
-
- typename MutableBufferSequence::const_iterator target_iter = target.begin();
- typename MutableBufferSequence::const_iterator target_end = target.end();
- std::size_t target_buffer_offset = 0;
-
- typename ConstBufferSequence::const_iterator source_iter = source.begin();
- typename ConstBufferSequence::const_iterator source_end = source.end();
- std::size_t source_buffer_offset = 0;
-
- while (total_bytes_copied != max_bytes_to_copy
- && target_iter != target_end && source_iter != source_end)
- {
- mutable_buffer target_buffer =
- mutable_buffer(*target_iter) + target_buffer_offset;
-
- const_buffer source_buffer =
- const_buffer(*source_iter) + source_buffer_offset;
-
- std::size_t bytes_copied = buffer_copy(target_buffer,
- source_buffer, max_bytes_to_copy - total_bytes_copied);
- total_bytes_copied += bytes_copied;
-
- if (bytes_copied == buffer_size(target_buffer))
- {
- ++target_iter;
- target_buffer_offset = 0;
- }
- else
- target_buffer_offset += bytes_copied;
-
- if (bytes_copied == buffer_size(source_buffer))
- {
- ++source_iter;
- source_buffer_offset = 0;
- }
- else
- source_buffer_offset += bytes_copied;
- }
-
- return total_bytes_copied;
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const ConstBufferSequence& source,
+ std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
+{
+ return detail::buffer_copy(
+ detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+ detail::buffer_sequence_cardinality<ConstBufferSequence>(),
+ boost::asio::buffer_sequence_begin(target),
+ boost::asio::buffer_sequence_end(target),
+ boost::asio::buffer_sequence_begin(source),
+ boost::asio::buffer_sequence_end(source), max_bytes_to_copy);
}
/*@}*/
diff --git a/boost/asio/buffered_read_stream.hpp b/boost/asio/buffered_read_stream.hpp
index ece138b599..9774ee9d52 100644
--- a/boost/asio/buffered_read_stream.hpp
+++ b/boost/asio/buffered_read_stream.hpp
@@ -26,7 +26,7 @@
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -56,6 +56,9 @@ public:
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+ /// The type of the executor associated with the object.
+ typedef typename lowest_layer_type::executor_type executor_type;
+
#if defined(GENERATING_DOCUMENTATION)
/// The default buffer size.
static const std::size_t default_buffer_size = implementation_defined;
@@ -97,11 +100,27 @@ public:
return next_layer_.lowest_layer();
}
- /// Get the io_service associated with the object.
- boost::asio::io_service& get_io_service()
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return next_layer_.lowest_layer().get_executor();
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_context()
+ {
+ return next_layer_.get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
@@ -110,9 +129,10 @@ public:
}
/// Close the stream.
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return next_layer_.close(ec);
+ next_layer_.close(ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Write the given data to the stream. Returns the number of bytes written.
@@ -140,15 +160,8 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- detail::async_result_init<
- WriteHandler, void (boost::system::error_code, std::size_t)> init(
+ return next_layer_.async_write_some(buffers,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-
- next_layer_.async_write_some(buffers,
- BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t)))(init.handler));
-
- return init.result.get();
}
/// Fill the buffer with some data. Returns the number of bytes placed in the
diff --git a/boost/asio/buffered_stream.hpp b/boost/asio/buffered_stream.hpp
index fae7c27113..a468370ffe 100644
--- a/boost/asio/buffered_stream.hpp
+++ b/boost/asio/buffered_stream.hpp
@@ -23,7 +23,7 @@
#include <boost/asio/buffered_stream_fwd.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -53,6 +53,9 @@ public:
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+ /// The type of the executor associated with the object.
+ typedef typename lowest_layer_type::executor_type executor_type;
+
/// Construct, passing the specified argument to initialise the next layer.
template <typename Arg>
explicit buffered_stream(Arg& a)
@@ -88,11 +91,27 @@ public:
return stream_impl_.lowest_layer();
}
- /// Get the io_service associated with the object.
- boost::asio::io_service& get_io_service()
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return stream_impl_.lowest_layer().get_executor();
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_context()
+ {
+ return stream_impl_.get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_service()
{
return stream_impl_.get_io_service();
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
@@ -101,9 +120,10 @@ public:
}
/// Close the stream.
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return stream_impl_.close(ec);
+ stream_impl_.close(ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Flush all data from the buffer to the next layer. Returns the number of
diff --git a/boost/asio/buffered_write_stream.hpp b/boost/asio/buffered_write_stream.hpp
index 5b8f31378d..a1b9c44016 100644
--- a/boost/asio/buffered_write_stream.hpp
+++ b/boost/asio/buffered_write_stream.hpp
@@ -25,7 +25,7 @@
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -56,6 +56,9 @@ public:
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+ /// The type of the executor associated with the object.
+ typedef typename lowest_layer_type::executor_type executor_type;
+
#if defined(GENERATING_DOCUMENTATION)
/// The default buffer size.
static const std::size_t default_buffer_size = implementation_defined;
@@ -97,11 +100,27 @@ public:
return next_layer_.lowest_layer();
}
- /// Get the io_service associated with the object.
- boost::asio::io_service& get_io_service()
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return next_layer_.lowest_layer().get_executor();
+ }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_context()
+ {
+ return next_layer_.get_io_context();
+ }
+
+ /// (Deprecated: Use get_executor().) Get the io_context associated with the
+ /// object.
+ boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
@@ -110,9 +129,10 @@ public:
}
/// Close the stream.
- boost::system::error_code close(boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- return next_layer_.close(ec);
+ next_layer_.close(ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@@ -175,15 +195,8 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- detail::async_result_init<
- ReadHandler, void (boost::system::error_code, std::size_t)> init(
+ return next_layer_.async_read_some(buffers,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-
- next_layer_.async_read_some(buffers,
- BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t)))(init.handler));
-
- return init.result.get();
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
diff --git a/boost/asio/buffers_iterator.hpp b/boost/asio/buffers_iterator.hpp
index c64b341b5b..bebbca1b9e 100644
--- a/boost/asio/buffers_iterator.hpp
+++ b/boost/asio/buffers_iterator.hpp
@@ -66,7 +66,44 @@ namespace detail
typedef buffers_iterator_types_helper<is_mutable> helper;
typedef typename helper::buffer_type buffer_type;
typedef typename helper::template byte_type<ByteType>::type byte_type;
+ typedef typename BufferSequence::const_iterator const_iterator;
};
+
+ template <typename ByteType>
+ struct buffers_iterator_types<mutable_buffer, ByteType>
+ {
+ typedef mutable_buffer buffer_type;
+ typedef ByteType byte_type;
+ typedef const mutable_buffer* const_iterator;
+ };
+
+ template <typename ByteType>
+ struct buffers_iterator_types<const_buffer, ByteType>
+ {
+ typedef const_buffer buffer_type;
+ typedef typename add_const<ByteType>::type byte_type;
+ typedef const const_buffer* const_iterator;
+ };
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+ template <typename ByteType>
+ struct buffers_iterator_types<mutable_buffers_1, ByteType>
+ {
+ typedef mutable_buffer buffer_type;
+ typedef ByteType byte_type;
+ typedef const mutable_buffer* const_iterator;
+ };
+
+ template <typename ByteType>
+ struct buffers_iterator_types<const_buffers_1, ByteType>
+ {
+ typedef const_buffer buffer_type;
+ typedef typename add_const<ByteType>::type byte_type;
+ typedef const const_buffer* const_iterator;
+ };
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
}
/// A random access iterator over the bytes in a buffer sequence.
@@ -77,6 +114,9 @@ private:
typedef typename detail::buffers_iterator_types<
BufferSequence, ByteType>::buffer_type buffer_type;
+ typedef typename detail::buffers_iterator_types<BufferSequence,
+ ByteType>::const_iterator buffer_sequence_iterator_type;
+
public:
/// The type used for the distance between two iterators.
typedef std::ptrdiff_t difference_type;
@@ -131,13 +171,13 @@ public:
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
{
buffers_iterator new_iter;
- new_iter.begin_ = buffers.begin();
- new_iter.current_ = buffers.begin();
- new_iter.end_ = buffers.end();
+ new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
+ new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
+ new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
while (new_iter.current_ != new_iter.end_)
{
new_iter.current_buffer_ = *new_iter.current_;
- if (boost::asio::buffer_size(new_iter.current_buffer_) > 0)
+ if (new_iter.current_buffer_.size() > 0)
break;
++new_iter.current_;
}
@@ -151,13 +191,13 @@ public:
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
{
buffers_iterator new_iter;
- new_iter.begin_ = buffers.begin();
- new_iter.current_ = buffers.begin();
- new_iter.end_ = buffers.end();
+ new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
+ new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
+ new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
while (new_iter.current_ != new_iter.end_)
{
buffer_type buffer = *new_iter.current_;
- new_iter.position_ += boost::asio::buffer_size(buffer);
+ new_iter.position_ += buffer.size();
++new_iter.current_;
}
return new_iter;
@@ -301,7 +341,8 @@ private:
// Dereference the iterator.
reference dereference() const
{
- return buffer_cast<pointer>(current_buffer_)[current_buffer_position_];
+ return static_cast<pointer>(
+ current_buffer_.data())[current_buffer_position_];
}
// Compare two iterators for equality.
@@ -318,7 +359,7 @@ private:
// Check if the increment can be satisfied by the current buffer.
++current_buffer_position_;
- if (current_buffer_position_ != boost::asio::buffer_size(current_buffer_))
+ if (current_buffer_position_ != current_buffer_.size())
return;
// Find the next non-empty buffer.
@@ -327,7 +368,7 @@ private:
while (current_ != end_)
{
current_buffer_ = *current_;
- if (boost::asio::buffer_size(current_buffer_) > 0)
+ if (current_buffer_.size() > 0)
return;
++current_;
}
@@ -347,12 +388,12 @@ private:
}
// Find the previous non-empty buffer.
- typename BufferSequence::const_iterator iter = current_;
+ buffer_sequence_iterator_type iter = current_;
while (iter != begin_)
{
--iter;
buffer_type buffer = *iter;
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ std::size_t buffer_size = buffer.size();
if (buffer_size > 0)
{
current_ = iter;
@@ -372,8 +413,7 @@ private:
for (;;)
{
std::ptrdiff_t current_buffer_balance
- = boost::asio::buffer_size(current_buffer_)
- - current_buffer_position_;
+ = current_buffer_.size() - current_buffer_position_;
// Check if the advance can be satisfied by the current buffer.
if (current_buffer_balance > n)
@@ -427,12 +467,12 @@ private:
}
// Find the previous non-empty buffer.
- typename BufferSequence::const_iterator iter = current_;
+ buffer_sequence_iterator_type iter = current_;
while (iter != begin_)
{
--iter;
buffer_type buffer = *iter;
- std::size_t buffer_size = boost::asio::buffer_size(buffer);
+ std::size_t buffer_size = buffer.size();
if (buffer_size > 0)
{
current_ = iter;
@@ -453,9 +493,9 @@ private:
buffer_type current_buffer_;
std::size_t current_buffer_position_;
- typename BufferSequence::const_iterator begin_;
- typename BufferSequence::const_iterator current_;
- typename BufferSequence::const_iterator end_;
+ buffer_sequence_iterator_type begin_;
+ buffer_sequence_iterator_type current_;
+ buffer_sequence_iterator_type end_;
std::size_t position_;
};
diff --git a/boost/asio/connect.hpp b/boost/asio/connect.hpp
index 635a8ad9bd..e31e8c92cd 100644
--- a/boost/asio/connect.hpp
+++ b/boost/asio/connect.hpp
@@ -18,6 +18,7 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -25,6 +26,36 @@
namespace boost {
namespace asio {
+namespace detail
+{
+ char (&has_iterator_helper(...))[2];
+
+ template <typename T>
+ char has_iterator_helper(T*, typename T::iterator* = 0);
+
+ template <typename T>
+ struct has_iterator_typedef
+ {
+ enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) };
+ };
+} // namespace detail
+
+/// Type trait used to determine whether a type is an endpoint sequence that can
+/// be used with with @c connect and @c async_connect.
+template <typename T>
+struct is_endpoint_sequence
+{
+#if defined(GENERATING_DOCUMENTATION)
+ /// The value member is true if the type may be used as an endpoint sequence.
+ static const bool value;
+#else
+ enum
+ {
+ value = detail::has_iterator_typedef<T>::value
+ };
+#endif
+};
+
/**
* @defgroup connect boost::asio::connect
*
@@ -42,27 +73,26 @@ namespace asio {
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
- * @returns On success, an iterator denoting the successfully connected
- * endpoint. Otherwise, the end iterator.
+ * @returns The successfully connected endpoint.
*
* @throws boost::system::system_error Thrown on failure. If the sequence is
* empty, the associated @c error_code is boost::asio::error::not_found.
* Otherwise, contains the error from the last connection attempt.
*
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
- *
* @par Example
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
* boost::asio::connect(s, r.resolve(q)); @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator>
-Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin);
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
+typename Protocol::endpoint connect(
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
/// Establishes a socket connection by trying each endpoint in a sequence.
/**
@@ -74,23 +104,19 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin);
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
* @param ec Set to indicate what error occurred, if any. If the sequence is
* empty, set to boost::asio::error::not_found. Otherwise, contains the error
* from the last connection attempt.
*
- * @returns On success, an iterator denoting the successfully connected
- * endpoint. Otherwise, the end iterator.
- *
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ * @returns On success, the successfully connected endpoint. Otherwise, a
+ * default-constructed endpoint.
*
* @par Example
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
* boost::system::error_code ec;
* boost::asio::connect(s, r.resolve(q), ec);
* if (ec)
@@ -98,11 +124,16 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin);
* // An error occurred.
* } @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator>
-Iterator connect(basic_socket<Protocol, SocketService>& s,
- Iterator begin, boost::system::error_code& ec);
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
+typename Protocol::endpoint connect(
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints, boost::system::error_code& ec,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
-/// Establishes a socket connection by trying each endpoint in a sequence.
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@@ -114,24 +145,80 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
*
* @param begin An iterator pointing to the start of a sequence of endpoints.
*
- * @param end An iterator pointing to the end of a sequence of endpoints.
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
*
* @returns On success, an iterator denoting the successfully connected
* endpoint. Otherwise, the end iterator.
*
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ Iterator begin, boost::system::error_code& ec,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @returns An iterator denoting the successfully connected endpoint.
+ *
* @throws boost::system::system_error Thrown on failure. If the sequence is
* empty, the associated @c error_code is boost::asio::error::not_found.
* Otherwise, contains the error from the last connection attempt.
*
* @par Example
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::resolver::iterator i = r.resolve(q), end;
- * tcp::socket s(io_service);
- * boost::asio::connect(s, i, end); @endcode
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * boost::asio::connect(s, e.begin(), e.end()); @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator>
-Iterator connect(basic_socket<Protocol, SocketService>& s,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -156,19 +243,19 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
* endpoint. Otherwise, the end iterator.
*
* @par Example
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::resolver::iterator i = r.resolve(q), end;
- * tcp::socket s(io_service);
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
* boost::system::error_code ec;
- * boost::asio::connect(s, i, end, ec);
+ * boost::asio::connect(s, e.begin(), e.end(), ec);
* if (ec)
* {
* // An error occurred.
* } @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator>
-Iterator connect(basic_socket<Protocol, SocketService>& s,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end, boost::system::error_code& ec);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -181,59 +268,54 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
- * @returns On success, an iterator denoting the successfully connected
- * endpoint. Otherwise, the end iterator.
+ * @returns The successfully connected endpoint.
*
* @throws boost::system::system_error Thrown on failure. If the sequence is
* empty, the associated @c error_code is boost::asio::error::not_found.
* Otherwise, contains the error from the last connection attempt.
*
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
- *
* @par Example
* The following connect condition function object can be used to output
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
- * tcp::resolver::iterator i = boost::asio::connect(
- * s, r.resolve(q), my_connect_condition());
- * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
+ * tcp::socket s(io_context);
+ * tcp::endpoint e = boost::asio::connect(s,
+ * r.resolve(q), my_connect_condition());
+ * std::cout << "Connected to: " << e << std::endl; @endcode
*/
-template <typename Protocol, typename SocketService,
- typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol, SocketService>& s,
- Iterator begin, ConnectCondition connect_condition);
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename EndpointSequence, typename ConnectCondition>
+typename Protocol::endpoint connect(
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints, ConnectCondition connect_condition,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
/// Establishes a socket connection by trying each endpoint in a sequence.
/**
@@ -245,67 +327,148 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
* @param ec Set to indicate what error occurred, if any. If the sequence is
* empty, set to boost::asio::error::not_found. Otherwise, contains the error
* from the last connection attempt.
*
- * @returns On success, an iterator denoting the successfully connected
- * endpoint. Otherwise, the end iterator.
- *
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ * @returns On success, the successfully connected endpoint. Otherwise, a
+ * default-constructed endpoint.
*
* @par Example
* The following connect condition function object can be used to output
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
* boost::system::error_code ec;
- * tcp::resolver::iterator i = boost::asio::connect(
- * s, r.resolve(q), my_connect_condition(), ec);
+ * tcp::endpoint e = boost::asio::connect(s,
+ * r.resolve(q), my_connect_condition(), ec);
* if (ec)
* {
* // An error occurred.
* }
* else
* {
- * std::cout << "Connected to: " << i->endpoint() << std::endl;
+ * std::cout << "Connected to: " << e << std::endl;
* } @endcode
*/
-template <typename Protocol, typename SocketService,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename EndpointSequence, typename ConnectCondition>
+typename Protocol::endpoint connect(
+ basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints, ConnectCondition connect_condition,
+ boost::system::error_code& ec,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ * const boost::system::error_code& ec,
+ * const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c 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.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
- ConnectCondition connect_condition, boost::system::error_code& ec);
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ Iterator begin, ConnectCondition connect_condition,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ * const boost::system::error_code& ec,
+ * const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c 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.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Iterator, typename ConnectCondition>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+ ConnectCondition connect_condition, boost::system::error_code& ec,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Establishes a socket connection by trying each endpoint in a sequence.
/**
@@ -323,19 +486,16 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
- * @returns On success, an iterator denoting the successfully connected
- * endpoint. Otherwise, the end iterator.
+ * @returns An iterator denoting the successfully connected endpoint.
*
* @throws boost::system::system_error Thrown on failure. If the sequence is
* empty, the associated @c error_code is boost::asio::error::not_found.
@@ -346,27 +506,27 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::resolver::iterator i = r.resolve(q), end;
- * tcp::socket s(io_service);
- * i = boost::asio::connect(s, i, end, my_connect_condition());
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * tcp::resolver::results_type::iterator i = boost::asio::connect(
+ * s, e.begin(), e.end(), my_connect_condition());
* std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
*/
-template <typename Protocol, typename SocketService,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -385,16 +545,14 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
* @param ec Set to indicate what error occurred, if any. If the sequence is
* empty, set to boost::asio::error::not_found. Otherwise, contains the error
@@ -408,23 +566,23 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::resolver::iterator i = r.resolve(q), end;
- * tcp::socket s(io_service);
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
* boost::system::error_code ec;
- * i = boost::asio::connect(s, i, end, my_connect_condition(), ec);
+ * tcp::resolver::results_type::iterator i = boost::asio::connect(
+ * s, e.begin(), e.end(), my_connect_condition());
* if (ec)
* {
* // An error occurred.
@@ -434,9 +592,9 @@ Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
* std::cout << "Connected to: " << i->endpoint() << std::endl;
* } @endcode
*/
-template <typename Protocol, typename SocketService,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol, SocketService>& s,
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
boost::system::error_code& ec);
@@ -461,7 +619,7 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
* @param handler The handler to be called when the connect operation
* completes. Copies will be made of the handler as required. The function
@@ -472,23 +630,19 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
* // error from the last connection attempt.
* const boost::system::error_code& error,
*
- * // On success, an iterator denoting the successfully
- * // connected endpoint. Otherwise, the end iterator.
- * Iterator iterator
+ * // On success, the successfully connected endpoint.
+ * // Otherwise, a default-constructed endpoint.
+ * const typename Protocol::endpoint& endpoint
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
- *
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ * boost::asio::io_context::post().
*
* @par Example
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
*
* // ...
*
@@ -498,11 +652,11 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
*
* void resolve_handler(
* const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
+ * tcp::resolver::results_type results)
* {
* if (!ec)
* {
- * boost::asio::async_connect(s, i, connect_handler);
+ * boost::asio::async_connect(s, results, connect_handler);
* }
* }
*
@@ -510,17 +664,65 @@ Iterator connect(basic_socket<Protocol, SocketService>& s,
*
* void connect_handler(
* const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
+ * const tcp::endpoint& endpoint)
* {
* // ...
* } @endcode
*/
-template <typename Protocol, typename SocketService,
- typename Iterator, typename ComposedConnectHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename EndpointSequence, typename RangeConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
+ void (boost::system::error_code, typename Protocol::endpoint))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints,
+ BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Asynchronously establishes a socket connection by trying each
+/// endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param 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:
+ * @code void handler(
+ * // Result of operation. if the sequence is empty, set to
+ * // boost::asio::error::not_found. Otherwise, contains the
+ * // error from the last connection attempt.
+ * const boost::system::error_code& error,
+ *
+ * // On success, an iterator denoting the successfully
+ * // connected endpoint. Otherwise, the end iterator.
+ * Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Iterator, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol, SocketService>& s,
- Iterator begin, BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler);
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Asynchronously establishes a socket connection by trying each endpoint in a
/// sequence.
@@ -553,46 +755,31 @@ async_connect(basic_socket<Protocol, SocketService>& s,
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
- * @code tcp::resolver r(io_service);
- * tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
- *
- * // ...
- *
- * r.async_resolve(q, resolve_handler);
- *
- * // ...
- *
- * void resolve_handler(
- * const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
- * {
- * if (!ec)
- * {
- * tcp::resolver::iterator end;
- * boost::asio::async_connect(s, i, end, connect_handler);
- * }
- * }
+ * @code std::vector<tcp::endpoint> endpoints = ...;
+ * tcp::socket s(io_context);
+ * boost::asio::async_connect(s,
+ * endpoints.begin(), endpoints.end(),
+ * connect_handler);
*
* // ...
*
* void connect_handler(
* const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
+ * std::vector<tcp::endpoint>::iterator i)
* {
* // ...
* } @endcode
*/
-template <typename Protocol, typename SocketService,
- typename Iterator, typename ComposedConnectHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+ typename Iterator, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol, SocketService>& s,
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end,
- BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler);
+ BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/// Asynchronously establishes a socket connection by trying each endpoint in a
/// sequence.
@@ -605,20 +792,18 @@ async_connect(basic_socket<Protocol, SocketService>& s,
* @param s The socket to be connected. If the socket is already open, it will
* be closed.
*
- * @param begin An iterator pointing to the start of a sequence of endpoints.
+ * @param endpoints A sequence of endpoints.
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
* @param handler The handler to be called when the connect operation
* completes. Copies will be made of the handler as required. The function
@@ -636,31 +821,26 @@ async_connect(basic_socket<Protocol, SocketService>& s,
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
- *
- * @note This overload assumes that a default constructed object of type @c
- * Iterator represents the end of the sequence. This is a valid assumption for
- * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ * boost::asio::io_context::post().
*
* @par Example
* The following connect condition function object can be used to output
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
*
* // ...
*
@@ -670,11 +850,11 @@ async_connect(basic_socket<Protocol, SocketService>& s,
*
* void resolve_handler(
* const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
+ * tcp::resolver::results_type results)
* {
* if (!ec)
* {
- * boost::asio::async_connect(s, i,
+ * boost::asio::async_connect(s, results,
* my_connect_condition(),
* connect_handler);
* }
@@ -684,7 +864,7 @@ async_connect(basic_socket<Protocol, SocketService>& s,
*
* void connect_handler(
* const boost::system::error_code& ec,
- * tcp::resolver::iterator i)
+ * const tcp::endpoint& endpoint)
* {
* if (ec)
* {
@@ -692,17 +872,76 @@ async_connect(basic_socket<Protocol, SocketService>& s,
* }
* else
* {
- * std::cout << "Connected to: " << i->endpoint() << std::endl;
+ * std::cout << "Connected to: " << endpoint << std::endl;
* }
* } @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator,
- typename ConnectCondition, typename ComposedConnectHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
+ void (boost::system::error_code, typename Protocol::endpoint))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+ const EndpointSequence& endpoints, ConnectCondition connect_condition,
+ BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
+ typename enable_if<is_endpoint_sequence<
+ EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Asynchronously establishes a socket connection by trying each
+/// endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ * const boost::system::error_code& ec,
+ * const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c 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.
+ *
+ * @param 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:
+ * @code void handler(
+ * // Result of operation. if the sequence is empty, set to
+ * // boost::asio::error::not_found. Otherwise, contains the
+ * // error from the last connection attempt.
+ * const boost::system::error_code& error,
+ *
+ * // On success, an iterator denoting the successfully
+ * // connected endpoint. Otherwise, the end iterator.
+ * Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ typename ConnectCondition, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
ConnectCondition connect_condition,
- BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler);
+ BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+ typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Asynchronously establishes a socket connection by trying each endpoint in a
/// sequence.
@@ -721,16 +960,14 @@ async_connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
*
* @param connect_condition A function object that is called prior to each
* connection attempt. The signature of the function object must be:
- * @code Iterator connect_condition(
+ * @code bool connect_condition(
* const boost::system::error_code& ec,
- * Iterator next); @endcode
+ * const typename Protocol::endpoint& next); @endcode
* The @c ec parameter contains the result from the most recent connect
* operation. Before the first connection attempt, @c ec is always set to
- * indicate success. The @c next parameter is an iterator pointing to the next
- * endpoint to be tried. The function object should return the next iterator,
- * but is permitted to return a different iterator so that endpoints may be
- * skipped. The implementation guarantees that the function object will never
- * be called with the end iterator.
+ * indicate success. The @c 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.
*
* @param handler The handler to be called when the connect operation
* completes. Copies will be made of the handler as required. The function
@@ -748,27 +985,26 @@ async_connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
- * boost::asio::io_service::post().
+ * boost::asio::io_context::post().
*
* @par Example
* The following connect condition function object can be used to output
* information about the individual connection attempts:
* @code struct my_connect_condition
* {
- * template <typename Iterator>
- * Iterator operator()(
+ * bool operator()(
* const boost::system::error_code& ec,
- * Iterator next)
+ * const::tcp::endpoint& next)
* {
* if (ec) std::cout << "Error: " << ec.message() << std::endl;
- * std::cout << "Trying: " << next->endpoint() << std::endl;
- * return next;
+ * std::cout << "Trying: " << next << std::endl;
+ * return true;
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_service);
+ * @code tcp::resolver r(io_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_service);
+ * tcp::socket s(io_context);
*
* // ...
*
@@ -805,13 +1041,13 @@ async_connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
* }
* } @endcode
*/
-template <typename Protocol, typename SocketService, typename Iterator,
- typename ConnectCondition, typename ComposedConnectHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ typename ConnectCondition, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol, SocketService>& s,
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
- BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler);
+ BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/*@}*/
diff --git a/boost/asio/coroutine.hpp b/boost/asio/coroutine.hpp
index c4763f8524..7ac354de82 100644
--- a/boost/asio/coroutine.hpp
+++ b/boost/asio/coroutine.hpp
@@ -206,7 +206,7 @@ class coroutine_ref;
* {
* do
* {
- * socket_.reset(new tcp::socket(io_service_));
+ * socket_.reset(new tcp::socket(io_context_));
* yield acceptor->async_accept(*socket_, *this);
* fork server(*this)();
* } while (is_parent());
@@ -228,7 +228,7 @@ class coroutine_ref;
* Note that @c 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_service::post().
+ * execution using something like io_context::post().
*
* @par Alternate macro names
*
@@ -291,7 +291,7 @@ private:
bail_out_of_coroutine: \
break; \
} \
- else case 0:
+ else /* fall-through */ case 0:
#define BOOST_ASIO_CORO_YIELD_IMPL(n) \
for (_coro_value = (n);;) \
@@ -303,12 +303,12 @@ private:
else \
switch (_coro_value ? 0 : 1) \
for (;;) \
- case -1: if (_coro_value) \
+ /* fall-through */ case -1: if (_coro_value) \
goto terminate_coroutine; \
else for (;;) \
- case 1: if (_coro_value) \
+ /* fall-through */ case 1: if (_coro_value) \
goto bail_out_of_coroutine; \
- else case 0:
+ else /* fall-through */ case 0:
#define BOOST_ASIO_CORO_FORK_IMPL(n) \
for (_coro_value = -(n);; _coro_value = (n)) \
diff --git a/boost/asio/datagram_socket_service.hpp b/boost/asio/datagram_socket_service.hpp
index 95f179acfd..35bc2f5feb 100644
--- a/boost/asio/datagram_socket_service.hpp
+++ b/boost/asio/datagram_socket_service.hpp
@@ -16,11 +16,14 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#include <cstddef>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
# include <boost/asio/detail/null_socket_service.hpp>
@@ -39,7 +42,7 @@ namespace asio {
template <typename Protocol>
class datagram_socket_service
#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_service::service
+ : public boost::asio::io_context::service
#else
: public boost::asio::detail::service_base<datagram_socket_service<Protocol> >
#endif
@@ -47,7 +50,7 @@ class datagram_socket_service
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
- static boost::asio::io_service::id id;
+ static boost::asio::io_context::id id;
#endif
/// The protocol type.
@@ -74,13 +77,6 @@ public:
typedef typename service_impl_type::implementation_type implementation_type;
#endif
- /// (Deprecated: Use native_handle_type.) The native socket type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_type;
-#else
- typedef typename service_impl_type::native_handle_type native_type;
-#endif
-
/// The native socket type.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
@@ -88,11 +84,11 @@ public:
typedef typename service_impl_type::native_handle_type native_handle_type;
#endif
- /// Construct a new datagram socket service for the specified io_service.
- explicit datagram_socket_service(boost::asio::io_service& io_service)
+ /// Construct a new datagram socket service for the specified io_context.
+ explicit datagram_socket_service(boost::asio::io_context& io_context)
: boost::asio::detail::service_base<
- datagram_socket_service<Protocol> >(io_service),
- service_impl_(io_service)
+ datagram_socket_service<Protocol> >(io_context),
+ service_impl_(io_context)
{
}
@@ -143,22 +139,23 @@ public:
}
// Open a new datagram socket implementation.
- boost::system::error_code open(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
const protocol_type& protocol, boost::system::error_code& ec)
{
if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM))
service_impl_.open(impl, protocol, ec);
else
ec = boost::asio::error::invalid_argument;
- return ec;
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to a datagram socket.
- boost::system::error_code assign(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
const protocol_type& protocol, const native_handle_type& native_socket,
boost::system::error_code& ec)
{
- return service_impl_.assign(impl, protocol, native_socket, ec);
+ service_impl_.assign(impl, protocol, native_socket, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
@@ -168,16 +165,18 @@ public:
}
/// Close a datagram socket implementation.
- boost::system::error_code close(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
boost::system::error_code& ec)
{
- return service_impl_.close(impl, ec);
+ service_impl_.close(impl, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
- /// (Deprecated: Use native_handle().) Get the native socket implementation.
- native_type native(implementation_type& impl)
+ /// Release ownership of the underlying socket.
+ native_handle_type release(implementation_type& impl,
+ boost::system::error_code& ec)
{
- return service_impl_.native_handle(impl);
+ return service_impl_.release(impl, ec);
}
/// Get the native socket implementation.
@@ -187,10 +186,11 @@ public:
}
/// Cancel all asynchronous operations associated with the socket.
- boost::system::error_code cancel(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
boost::system::error_code& ec)
{
- return service_impl_.cancel(impl, ec);
+ service_impl_.cancel(impl, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
@@ -208,17 +208,19 @@ public:
}
// Bind the datagram socket to the specified local endpoint.
- boost::system::error_code bind(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
const endpoint_type& endpoint, boost::system::error_code& ec)
{
- return service_impl_.bind(impl, endpoint, ec);
+ service_impl_.bind(impl, endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the datagram socket to the specified endpoint.
- boost::system::error_code connect(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
const endpoint_type& peer_endpoint, boost::system::error_code& ec)
{
- return service_impl_.connect(impl, peer_endpoint, ec);
+ service_impl_.connect(impl, peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
@@ -229,37 +231,39 @@ public:
const endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
{
- detail::async_result_init<
- ConnectHandler, void (boost::system::error_code)> init(
- BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
+ async_completion<ConnectHandler,
+ void (boost::system::error_code)> init(handler);
- service_impl_.async_connect(impl, peer_endpoint, init.handler);
+ service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
return init.result.get();
}
/// Set a socket option.
template <typename SettableSocketOption>
- boost::system::error_code set_option(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
const SettableSocketOption& option, boost::system::error_code& ec)
{
- return service_impl_.set_option(impl, option, ec);
+ service_impl_.set_option(impl, option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get a socket option.
template <typename GettableSocketOption>
- boost::system::error_code get_option(const implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
GettableSocketOption& option, boost::system::error_code& ec) const
{
- return service_impl_.get_option(impl, option, ec);
+ service_impl_.get_option(impl, option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
template <typename IoControlCommand>
- boost::system::error_code io_control(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
IoControlCommand& command, boost::system::error_code& ec)
{
- return service_impl_.io_control(impl, command, ec);
+ service_impl_.io_control(impl, command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
@@ -269,10 +273,11 @@ public:
}
/// Sets the non-blocking mode of the socket.
- boost::system::error_code non_blocking(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
bool mode, boost::system::error_code& ec)
{
- return service_impl_.non_blocking(impl, mode, ec);
+ service_impl_.non_blocking(impl, mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
@@ -282,10 +287,11 @@ public:
}
/// Sets the non-blocking mode of the native socket implementation.
- boost::system::error_code native_non_blocking(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
bool mode, boost::system::error_code& ec)
{
- return service_impl_.native_non_blocking(impl, mode, ec);
+ service_impl_.native_non_blocking(impl, mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint.
@@ -303,10 +309,36 @@ public:
}
/// Disable sends or receives on the socket.
- boost::system::error_code shutdown(implementation_type& impl,
+ BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
socket_base::shutdown_type what, boost::system::error_code& ec)
{
- return service_impl_.shutdown(impl, what, ec);
+ service_impl_.shutdown(impl, what, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
+ socket_base::wait_type w, boost::system::error_code& ec)
+ {
+ service_impl_.wait(impl, w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the socket to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(implementation_type& impl, socket_base::wait_type w,
+ BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ service_impl_.async_wait(impl, w, init.completion_handler);
+
+ return init.result.get();
}
/// Send the given data to the peer.
@@ -326,11 +358,10 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- detail::async_result_init<
- WriteHandler, void (boost::system::error_code, std::size_t)> init(
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
- service_impl_.async_send(impl, buffers, flags, init.handler);
+ service_impl_.async_send(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
@@ -353,12 +384,11 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- detail::async_result_init<
- WriteHandler, void (boost::system::error_code, std::size_t)> init(
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_send_to(impl, buffers,
- destination, flags, init.handler);
+ destination, flags, init.completion_handler);
return init.result.get();
}
@@ -381,11 +411,10 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- detail::async_result_init<
- ReadHandler, void (boost::system::error_code, std::size_t)> init(
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
- service_impl_.async_receive(impl, buffers, flags, init.handler);
+ service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
@@ -409,21 +438,20 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- detail::async_result_init<
- ReadHandler, void (boost::system::error_code, std::size_t)> init(
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_receive_from(impl, buffers,
- sender_endpoint, flags, init.handler);
+ sender_endpoint, flags, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
+ void shutdown()
{
- service_impl_.shutdown_service();
+ service_impl_.shutdown();
}
// The platform-specific implementation.
@@ -435,4 +463,6 @@ private:
#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
diff --git a/boost/asio/deadline_timer_service.hpp b/boost/asio/deadline_timer_service.hpp
index 26dcb42e4c..d109815188 100644
--- a/boost/asio/deadline_timer_service.hpp
+++ b/boost/asio/deadline_timer_service.hpp
@@ -17,15 +17,16 @@
#include <boost/asio/detail/config.hpp>
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/deadline_timer_service.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/io_context.hpp>
#include <boost/asio/time_traits.hpp>
-#include <boost/asio/detail/timer_queue_ptime.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -37,7 +38,7 @@ template <typename TimeType,
typename TimeTraits = boost::asio::time_traits<TimeType> >
class deadline_timer_service
#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_service::service
+ : public boost::asio::io_context::service
#else
: public boost::asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >
@@ -46,7 +47,7 @@ class deadline_timer_service
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
- static boost::asio::io_service::id id;
+ static boost::asio::io_context::id id;
#endif
/// The time traits type.
@@ -70,11 +71,11 @@ public:
typedef typename service_impl_type::implementation_type implementation_type;
#endif
- /// Construct a new timer service for the specified io_service.
- explicit deadline_timer_service(boost::asio::io_service& io_service)
+ /// Construct a new timer service for the specified io_context.
+ explicit deadline_timer_service(boost::asio::io_context& io_context)
: boost::asio::detail::service_base<
- deadline_timer_service<TimeType, TimeTraits> >(io_service),
- service_impl_(io_service)
+ deadline_timer_service<TimeType, TimeTraits> >(io_context),
+ service_impl_(io_context)
{
}
@@ -106,7 +107,7 @@ public:
/// Get the expiry time for the timer as an absolute time.
time_type expires_at(const implementation_type& impl) const
{
- return service_impl_.expires_at(impl);
+ return service_impl_.expiry(impl);
}
/// Set the expiry time for the timer as an absolute time.
@@ -119,14 +120,14 @@ public:
/// Get the expiry time for the timer relative to now.
duration_type expires_from_now(const implementation_type& impl) const
{
- return service_impl_.expires_from_now(impl);
+ return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
}
/// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, boost::system::error_code& ec)
{
- return service_impl_.expires_from_now(impl, expiry_time, ec);
+ return service_impl_.expires_after(impl, expiry_time, ec);
}
// Perform a blocking wait on the timer.
@@ -142,20 +143,19 @@ public:
async_wait(implementation_type& impl,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- detail::async_result_init<
- WaitHandler, void (boost::system::error_code)> init(
- BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+ async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
- service_impl_.async_wait(impl, init.handler);
+ service_impl_.async_wait(impl, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
+ void shutdown()
{
- service_impl_.shutdown_service();
+ service_impl_.shutdown();
}
// The platform-specific implementation.
@@ -170,4 +170,6 @@ private:
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
diff --git a/boost/asio/defer.hpp b/boost/asio/defer.hpp
new file mode 100644
index 0000000000..966bfb4e14
--- /dev/null
+++ b/boost/asio/defer.hpp
@@ -0,0 +1,109 @@
+//
+// defer.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DEFER_HPP
+#define BOOST_ASIO_DEFER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/is_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Submits a completion token or function object for execution.
+/**
+ * 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 <tt>defer()</tt>.
+ *
+ * This function has the following effects:
+ *
+ * @li Constructs a function object handler of type @c Handler, initialized
+ * with <tt>handler(forward<CompletionToken>(token))</tt>.
+ *
+ * @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
+ * initializing the object as <tt>result(handler)</tt>.
+ *
+ * @li Obtains the handler's associated executor object @c ex by performing
+ * <tt>get_associated_executor(handler)</tt>.
+ *
+ * @li Obtains the handler's associated allocator object @c alloc by performing
+ * <tt>get_associated_allocator(handler)</tt>.
+ *
+ * @li Performs <tt>ex.defer(std::move(handler), alloc)</tt>.
+ *
+ * @li Returns <tt>result.get()</tt>.
+ */
+template <typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+ BOOST_ASIO_MOVE_ARG(CompletionToken) token);
+
+/// Submits a completion token or function object for execution.
+/**
+ * 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 <tt>defer()</tt>.
+ *
+ * This function has the following effects:
+ *
+ * @li Constructs a function object handler of type @c Handler, initialized
+ * with <tt>handler(forward<CompletionToken>(token))</tt>.
+ *
+ * @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
+ * initializing the object as <tt>result(handler)</tt>.
+ *
+ * @li Obtains the handler's associated executor object @c ex1 by performing
+ * <tt>get_associated_executor(handler)</tt>.
+ *
+ * @li Creates a work object @c w by performing <tt>make_work(ex1)</tt>.
+ *
+ * @li Obtains the handler's associated allocator object @c alloc by performing
+ * <tt>get_associated_allocator(handler)</tt>.
+ *
+ * @li Constructs a function object @c f with a function call operator that
+ * performs <tt>ex1.dispatch(std::move(handler), alloc)</tt> followed by
+ * <tt>w.reset()</tt>.
+ *
+ * @li Performs <tt>Executor(ex).defer(std::move(f), alloc)</tt>.
+ *
+ * @li Returns <tt>result.get()</tt>.
+ */
+template <typename Executor, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+ const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
+ typename enable_if<is_executor<Executor>::value>::type* = 0);
+
+/// Submits a completion token or function object for execution.
+/**
+ * @returns <tt>defer(ctx.get_executor(), forward<CompletionToken>(token))</tt>.
+ */
+template <typename ExecutionContext, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+ ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
+ typename enable_if<is_convertible<
+ ExecutionContext&, execution_context&>::value>::type* = 0);
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/defer.hpp>
+
+#endif // BOOST_ASIO_DEFER_HPP
diff --git a/boost/asio/detail/addressof.hpp b/boost/asio/detail/addressof.hpp
deleted file mode 100644
index cc1099764d..0000000000
--- a/boost/asio/detail/addressof.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// detail/addressof.hpp
-// ~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_ASIO_DETAIL_ADDRESSOF_HPP
-#define BOOST_ASIO_DETAIL_ADDRESSOF_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-# include <memory>
-#else // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-# include <boost/utility/addressof.hpp>
-#endif // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-#if defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-using std::addressof;
-#else // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-using boost::addressof;
-#endif // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#endif // BOOST_ASIO_DETAIL_ADDRESSOF_HPP
diff --git a/boost/asio/detail/bind_handler.hpp b/boost/asio/detail/bind_handler.hpp
index 0f3672edab..b55c2acd5e 100644
--- a/boost/asio/detail/bind_handler.hpp
+++ b/boost/asio/detail/bind_handler.hpp
@@ -16,9 +16,12 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
+#include <boost/asio/associated_allocator.hpp>
+#include <boost/asio/associated_executor.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -30,8 +33,9 @@ template <typename Handler, typename Arg1>
class binder1
{
public:
- binder1(const Handler& handler, const Arg1& arg1)
- : handler_(handler),
+ template <typename T>
+ binder1(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1)
+ : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
arg1_(arg1)
{
}
@@ -42,6 +46,20 @@ public:
{
}
+#if defined(BOOST_ASIO_HAS_MOVE)
+ binder1(const binder1& other)
+ : handler_(other.handler_),
+ arg1_(other.arg1_)
+ {
+ }
+
+ binder1(binder1&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
void operator()()
{
handler_(static_cast<const Arg1&>(arg1_));
@@ -98,18 +116,21 @@ inline void asio_handler_invoke(const Function& function,
}
template <typename Handler, typename Arg1>
-inline binder1<Handler, Arg1> bind_handler(Handler handler,
- const Arg1& arg1)
+inline binder1<typename decay<Handler>::type, Arg1> bind_handler(
+ BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1)
{
- return binder1<Handler, Arg1>(handler, arg1);
+ return binder1<typename decay<Handler>::type, Arg1>(0,
+ BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1);
}
template <typename Handler, typename Arg1, typename Arg2>
class binder2
{
public:
- binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
- : handler_(handler),
+ template <typename T>
+ binder2(int, BOOST_ASIO_MOVE_ARG(T) handler,
+ const Arg1& arg1, const Arg2& arg2)
+ : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
arg1_(arg1),
arg2_(arg2)
{
@@ -122,6 +143,22 @@ public:
{
}
+#if defined(BOOST_ASIO_HAS_MOVE)
+ binder2(const binder2& other)
+ : handler_(other.handler_),
+ arg1_(other.arg1_),
+ arg2_(other.arg2_)
+ {
+ }
+
+ binder2(binder2&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
void operator()()
{
handler_(static_cast<const Arg1&>(arg1_),
@@ -180,27 +217,29 @@ inline void asio_handler_invoke(const Function& function,
}
template <typename Handler, typename Arg1, typename Arg2>
-inline binder2<Handler, Arg1, Arg2> bind_handler(Handler handler,
- const Arg1& arg1, const Arg2& arg2)
+inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(
+ BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2)
{
- return binder2<Handler, Arg1, Arg2>(handler, arg1, arg2);
+ return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,
+ BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);
}
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
class binder3
{
public:
- binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3)
- : handler_(handler),
+ template <typename T>
+ binder3(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3)
+ : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
arg1_(arg1),
arg2_(arg2),
arg3_(arg3)
{
}
- binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3)
+ binder3(Handler& handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3)
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
arg1_(arg1),
arg2_(arg2),
@@ -208,11 +247,28 @@ public:
{
}
+#if defined(BOOST_ASIO_HAS_MOVE)
+ binder3(const binder3& other)
+ : handler_(other.handler_),
+ arg1_(other.arg1_),
+ arg2_(other.arg2_),
+ arg3_(other.arg3_)
+ {
+ }
+
+ binder3(binder3&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+ arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
void operator()()
{
handler_(static_cast<const Arg1&>(arg1_),
- static_cast<const Arg2&>(arg2_),
- static_cast<const Arg3&>(arg3_));
+ static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
}
void operator()() const
@@ -251,8 +307,8 @@ inline bool asio_handler_is_continuation(
this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3>
+template <typename Function, typename Handler,
+ typename Arg1, typename Arg2, typename Arg3>
inline void asio_handler_invoke(Function& function,
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
@@ -260,8 +316,8 @@ inline void asio_handler_invoke(Function& function,
function, this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3>
+template <typename Function, typename Handler,
+ typename Arg1, typename Arg2, typename Arg3>
inline void asio_handler_invoke(const Function& function,
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
@@ -270,20 +326,23 @@ inline void asio_handler_invoke(const Function& function,
}
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
-inline binder3<Handler, Arg1, Arg2, Arg3> bind_handler(Handler handler,
- const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
+inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(
+ BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,
+ const Arg3& arg3)
{
- return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
+ return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,
+ BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
+template <typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
class binder4
{
public:
- binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3, const Arg4& arg4)
- : handler_(handler),
+ template <typename T>
+ binder4(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
+ : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
arg1_(arg1),
arg2_(arg2),
arg3_(arg3),
@@ -291,8 +350,8 @@ public:
{
}
- binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3, const Arg4& arg4)
+ binder4(Handler& handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
arg1_(arg1),
arg2_(arg2),
@@ -301,11 +360,30 @@ public:
{
}
+#if defined(BOOST_ASIO_HAS_MOVE)
+ binder4(const binder4& other)
+ : handler_(other.handler_),
+ arg1_(other.arg1_),
+ arg2_(other.arg2_),
+ arg3_(other.arg3_),
+ arg4_(other.arg4_)
+ {
+ }
+
+ binder4(binder4&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+ arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
+ arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
void operator()()
{
handler_(static_cast<const Arg1&>(arg1_),
- static_cast<const Arg2&>(arg2_),
- static_cast<const Arg3&>(arg3_),
+ static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
static_cast<const Arg4&>(arg4_));
}
@@ -322,8 +400,8 @@ public:
Arg4 arg4_;
};
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
+template <typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
inline void* asio_handler_allocate(std::size_t size,
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
@@ -331,8 +409,8 @@ inline void* asio_handler_allocate(std::size_t size,
size, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
+template <typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
@@ -340,8 +418,8 @@ inline void asio_handler_deallocate(void* pointer, std::size_t size,
pointer, size, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
+template <typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
inline bool asio_handler_is_continuation(
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
@@ -349,8 +427,8 @@ inline bool asio_handler_is_continuation(
this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3, typename Arg4>
+template <typename Function, typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
inline void asio_handler_invoke(Function& function,
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
@@ -358,8 +436,8 @@ inline void asio_handler_invoke(Function& function,
function, this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3, typename Arg4>
+template <typename Function, typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
inline void asio_handler_invoke(const Function& function,
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
@@ -367,24 +445,25 @@ inline void asio_handler_invoke(const Function& function,
function, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4>
-inline binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(
- Handler handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3, const Arg4& arg4)
+template <typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4>
+inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>
+bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
{
- return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
- arg4);
+ return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,
+ BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4, typename Arg5>
+template <typename Handler, typename Arg1, typename Arg2,
+ typename Arg3, typename Arg4, typename Arg5>
class binder5
{
public:
- binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
- : handler_(handler),
+ template <typename T>
+ binder5(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+ : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
arg1_(arg1),
arg2_(arg2),
arg3_(arg3),
@@ -404,13 +483,33 @@ public:
{
}
+#if defined(BOOST_ASIO_HAS_MOVE)
+ binder5(const binder5& other)
+ : handler_(other.handler_),
+ arg1_(other.arg1_),
+ arg2_(other.arg2_),
+ arg3_(other.arg3_),
+ arg4_(other.arg4_),
+ arg5_(other.arg5_)
+ {
+ }
+
+ binder5(binder5&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+ arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
+ arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_)),
+ arg5_(BOOST_ASIO_MOVE_CAST(Arg5)(other.arg5_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
void operator()()
{
handler_(static_cast<const Arg1&>(arg1_),
- static_cast<const Arg2&>(arg2_),
- static_cast<const Arg3&>(arg3_),
- static_cast<const Arg4&>(arg4_),
- static_cast<const Arg5&>(arg5_));
+ static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
+ static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
}
void operator()() const
@@ -427,8 +526,8 @@ public:
Arg5 arg5_;
};
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4, typename Arg5>
+template <typename Handler, typename Arg1, typename Arg2,
+ typename Arg3, typename Arg4, typename Arg5>
inline void* asio_handler_allocate(std::size_t size,
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
@@ -436,8 +535,8 @@ inline void* asio_handler_allocate(std::size_t size,
size, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4, typename Arg5>
+template <typename Handler, typename Arg1, typename Arg2,
+ typename Arg3, typename Arg4, typename Arg5>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
@@ -445,8 +544,8 @@ inline void asio_handler_deallocate(void* pointer, std::size_t size,
pointer, size, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4, typename Arg5>
+template <typename Handler, typename Arg1, typename Arg2,
+ typename Arg3, typename Arg4, typename Arg5>
inline bool asio_handler_is_continuation(
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
@@ -454,8 +553,8 @@ inline bool asio_handler_is_continuation(
this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3, typename Arg4, typename Arg5>
+template <typename Function, typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4, typename Arg5>
inline void asio_handler_invoke(Function& function,
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
@@ -463,8 +562,8 @@ inline void asio_handler_invoke(Function& function,
function, this_handler->handler_);
}
-template <typename Function, typename Handler, typename Arg1, typename Arg2,
- typename Arg3, typename Arg4, typename Arg5>
+template <typename Function, typename Handler, typename Arg1,
+ typename Arg2, typename Arg3, typename Arg4, typename Arg5>
inline void asio_handler_invoke(const Function& function,
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
@@ -472,17 +571,245 @@ inline void asio_handler_invoke(const Function& function,
function, this_handler->handler_);
}
-template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
- typename Arg4, typename Arg5>
-inline binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(
- Handler handler, const Arg1& arg1, const Arg2& arg2,
- const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+template <typename Handler, typename Arg1, typename Arg2,
+ typename Arg3, typename Arg4, typename Arg5>
+inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>
+bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
+ const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+{
+ return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
+ BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);
+}
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+
+template <typename Handler, typename Arg1>
+class move_binder1
+{
+public:
+ move_binder1(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
+ BOOST_ASIO_MOVE_ARG(Arg1) arg1)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1))
+ {
+ }
+
+ move_binder1(move_binder1&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
+ {
+ }
+
+ void operator()()
+ {
+ handler_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
+ }
+
+//private:
+ Handler handler_;
+ Arg1 arg1_;
+};
+
+template <typename Handler, typename Arg1>
+inline void* asio_handler_allocate(std::size_t size,
+ move_binder1<Handler, Arg1>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ move_binder1<Handler, Arg1>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline bool asio_handler_is_continuation(
+ move_binder1<Handler, Arg1>* this_handler)
+{
+ return boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1>
+inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
+ move_binder1<Handler, Arg1>* this_handler)
+{
+ boost_asio_handler_invoke_helpers::invoke(
+ BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+class move_binder2
+{
+public:
+ move_binder2(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
+ const Arg1& arg1, BOOST_ASIO_MOVE_ARG(Arg2) arg2)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ arg1_(arg1),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(arg2))
+ {
+ }
+
+ move_binder2(move_binder2&& other)
+ : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+ arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
+ {
+ }
+
+ void operator()()
+ {
+ handler_(static_cast<const Arg1&>(arg1_),
+ BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
+ }
+
+//private:
+ Handler handler_;
+ Arg1 arg1_;
+ Arg2 arg2_;
+};
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void* asio_handler_allocate(std::size_t size,
+ move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline bool asio_handler_is_continuation(
+ move_binder2<Handler, Arg1, Arg2>* this_handler)
{
- return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
- arg3, arg4, arg5);
+ return boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
}
+template <typename Function, typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
+ move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+ boost_asio_handler_invoke_helpers::invoke(
+ BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
+}
+
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
} // namespace detail
+
+template <typename Handler, typename Arg1, typename Allocator>
+struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
+{
+ typedef typename associated_allocator<Handler, Allocator>::type type;
+
+ static type get(const detail::binder1<Handler, Arg1>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
+struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
+{
+ typedef typename associated_allocator<Handler, Allocator>::type type;
+
+ static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename Handler, typename Arg1, typename Executor>
+struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
+{
+ typedef typename associated_executor<Handler, Executor>::type type;
+
+ static type get(const detail::binder1<Handler, Arg1>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<Handler, Executor>::get(h.handler_, ex);
+ }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Executor>
+struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
+{
+ typedef typename associated_executor<Handler, Executor>::type type;
+
+ static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<Handler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+
+template <typename Handler, typename Arg1, typename Allocator>
+struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
+{
+ typedef typename associated_allocator<Handler, Allocator>::type type;
+
+ static type get(const detail::move_binder1<Handler, Arg1>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
+struct associated_allocator<
+ detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
+{
+ typedef typename associated_allocator<Handler, Allocator>::type type;
+
+ static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
+ const Allocator& a = Alloca